vaved
vaved

Reputation: 129

How do search in some indexes in ElasticSearch

I use library elastica PHP. At first before using search I need load index:

// Load index
$elasticaIndex = $elasticaClient->getIndex('twit');

And after I can do query:

$elasticaResultSet = $elasticaIndex->search($elasticaQuery);

How to build search to some indexes, not only twit?

I use the next:

public function Query($value, $elasticaIndex)
    {
        $elasticaQueryString = new \Elastica\Query\QueryString();
        $elasticaQueryString->setQuery((string)$value);

        // Create the actual search object with some data.
        $elasticaQuery = new \Elastica\Query();
        $elasticaQuery->setQuery($elasticaQueryString);

        //Search on the index.
        $elasticaResultSet = $elasticaIndex->search($elasticaQuery);
        return $elasticaResultSet->getResults();
    }

Adding documents:

private function addDocument($data, $index)
    {
        $this->elasticaIndex = $this->elastic->getIndex($name);
        $this->elasticaIndex->create(array(), true);

        foreach ($data as $id => $val) {
            $documents[] = new \Elastica\Document(
                $id, $val
            );
        }

        $this->elasticaType->addDocuments($documents);
        $this->elasticaType->getIndex()->refresh();
    }

Is it right code?

Creating indexes and mapping:

For create some indexes I use function wuth param $name that means name of index:

private function createIndex($name)
    {
        $this->elasticaIndex = $this->elastic->getIndex($name);
        $this->elasticaIndex->create(array(
            'number_of_shards' => 4,
            'number_of_replicas' => 1,
            'analysis' => array(
                'analyzer' => array(
                    $name.'Analyzer' => array(
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => array('lowercase', 'mySnowball')
                    ),
                    $name.'Analyzer' => array(
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => array('standard', 'lowercase', 'mySnowball')
                    )
                )
                /*'filter' => array(
                    'mySnowball' => array(
                        'type' => 'snowball',
                        'language' => 'German'
                    )
                )*/
            )
        ), true);

        $this->elasticaType = $this->elasticaIndex->getType($name);
    }

Please, notice attention on 'analyzer' => array() in create() method. It needs for mapping.

Also I have constructor, that creates mapping. For this constructor I pass $elasticaType is name of index_analyzer, search_analyzer from created indexes above.

 function __construct($elasticaType)
 {
    parent::__construct();
    $elasticaIndex = $this->elastic->getIndex($elasticaType);
    $elasticaType = $elasticaIndex->getType($elasticaType);

    $this->mapping = new \Elastica\Type\Mapping();
    $this->mapping->setType($elasticaType);
    $this->mapping->setParam('index_analyzer', $elasticaType.'Analyzer');
    $this->mapping->setParam('search_analyzer', $elasticaType.'Analyzer');
}

When I try to create mapping I get error:

Fatal error: Uncaught exception 'Elastica\Exception\ResponseException' with message 'MapperParsingException[Analyzer [Analyzer] not found for index_analyzer setting on root type [users]]' in 

Upvotes: 0

Views: 377

Answers (1)

Raphaël Malié
Raphaël Malié

Reputation: 4012

You can search in several index with the \Elastica\Search class. Here is the version updated of your code :

public function Query($value, $elasticaClient)
{
    $elasticaQueryString = new \Elastica\Query\QueryString();
    $elasticaQueryString->setQuery((string)$value);

    // Create the actual search object with some data.
    $elasticaQuery = new \Elastica\Query();
    $elasticaQuery->setQuery($elasticaQueryString);

    //Search
    $search = new \Elastica\Search($elasticaClient);
    $search->addIndex('twit');
    $search->addIndex('an_other_index');
    $elasticaResultSet = $search->search($elasticaQuery);

    return $elasticaResultSet->getResults();
}

Since you are searching on several index, you don't need to pass your $elasticaIndex variable, but instead your $elasticaClient.

If you want to keep the $elasticaIndex way (for some technical reasons), you can achieve what you want to do this way :

public function Query($value, $elasticaIndex)
{
    $elasticaQueryString = new \Elastica\Query\QueryString();
    $elasticaQueryString->setQuery((string)$value);

    // Create the actual search object with some data.
    $elasticaQuery = new \Elastica\Query();
    $elasticaQuery->setQuery($elasticaQueryString);

    //Search
    $search = $elasticaIndex->createSearch();
    $search->addIndex('an_other_index');
    $elasticaResultSet = $search->search($elasticaQuery);

    return $elasticaResultSet->getResults();
}

For your last question with analyzers, you override the var $elasticaType when you does :

$elasticaType = $elasticaIndex->getType($elasticaType);

You should instead do something like this :

 function __construct($name)
 {
    parent::__construct();
    $elasticaIndex = $this->elastic->getIndex($name);
    $elasticaType = $elasticaIndex->getType($name);

    $this->mapping = new \Elastica\Type\Mapping();
    $this->mapping->setType($elasticaType);
    $this->mapping->setParam('index_analyzer', $name.'Analyzer');
    $this->mapping->setParam('search_analyzer', $name.'Analyzer');
}

Upvotes: 1

Related Questions