Elastic Search: How to Get the Most Explained Terms

im implaymeting elasticsearch in symfony2 project with fos_elastica.

everything works fine (data indexing, updating, etc.)

I'm currently looking for an analysis of user behavior: I would like to get the 10 most popular search queries or keywords for a second request.

eg:

if 45% of requests relate to yellow balloons and 45% to red balloons, I would like to suggest several yellow or red balloons on my homepage

First, I thought about creating a symfony2 object to save a custom timestamped search, and then calculated the last 1000 searches to get the most famous keywords. although it will certainly work, it will be a killer resource.

I was wondering if elasticsearch would be able to provide them and how to implement them.

I read that I can create an index to store my user queries (and that would be terrible, because I could use graphs to calculate them very easily), but I don’t know how to do this, from symfony2 without a dedicated object.

+4
source share
1 answer

Well, I finally got it!

Here are a few steps:

1) create a new index in config.yml with a special display for keyword searches

in config.yml

indexes:
    your_index:
        types:
            search:
                mappings:
                    value: {type:string}
                    date : {type:date}
                    provider: acme\AppBundle\Service\SearchProvider

2) create a new SearchProvider class in the service directory

in acme\Appbundle\Service\SearchProvider

<?php


namespace acme\AppBundle\Service;

use FOS\ElasticaBundle\Provider\ProviderInterface;
use Elastica\Type;
use Elastica\Document;

class SearchProvider implements ProviderInterface
{
protected   $searchType;
private     $search;

public function __construct(Type $searchType)
{
    $this->searchType = $searchType;
}

// the function you will call from your service
public function add( $search )
{
    $this->search = $search;
    $this->populate();
}

/**
 * Insert the repository objects in the type index
 *
 * @param \Closure $loggerClosure
 * @param array    $options
 */
public function populate(\Closure $loggerClosure = null, array $options = array())
{
    if ($loggerClosure) {
        $loggerClosure('Indexing users');
    }

    $date  = time();

    $document = new Document();
    $document->setData(array('value' => $this->search, 'date' => $date ) );
    $this->userType->addDocuments(array($document));
    $this->userType->getIndex()->refresh();
}
}

3) create a new service declaration in your service.yml service

services:
acme.search_provider:
    class: acme\AppBundle\Service\SearchProvider
    arguments:
        - @fos_elastica.index.recetas.search
    tags:
        - { name: fos_elastica.provider, index: your_index, type: search }

4) call your service to store new requests, such as

$this->get("acme.search_provider")->add("kapoue"); 

kapoue will be added to the search queries.

5)

    $es                 = $this->get('fos_elastica.index.acme.search');
    $query              = new \Elastica\Query();

    $aggregation        = new \Elastica\Aggregation\Terms("top_hits");
    $aggregation->setField('value');
    $aggregation->setSize( 3 );

    $query->addAggregation($aggregation);

    $result             = $es->search($query);
    $mostResearched     = $result->getAggregation("top_hits");

    print_r ( $mostResearched ); die();
+3

All Articles