Skip to content

9. ElasticSearch

ddis edited this page May 7, 2018 · 13 revisions

FilterParams types

// 1. Filter params for AttributeFilter
$params = new AttributeFilterParams(int $attributeId, array $attributeValueIds);

// 2. Filter params for IndexFilter
$params = new IndexFilterParams(array $entities);

// 3. Filter params for MatchFilter/MatchPhraseFilter
$params = new MatchFilterParams(string $field, string $value);

// 4. Filter params for PriceRangeFilter
$params = new PriceRangeFilterParams(int $priceMin = null, int $priceMax = null);

// 5. Filter params for TermsFilter
$params = new TermsFilterParams(string $field, array $values);

Filter types

// 1. Filter for selecting index to search in
$params = new IndexFilterParams([Product::class, Document::class, Page::class]); // entities list
$indexFilter = new ElasticSearchIndexFilter($params);

// 2. Filter for using terms for search
$params = new TermsFilterParams('brandId', [333, 50]); // field, values
$termsFilter = new TermsFilter($params));

// 3. Filter for selecting price range
$params = new PriceRangeFilterParams(100, 6060); // priceMin, priceMax
$priceRangeFilter = new PriceRangeFilter($params);

// 4. Match filter
$params = new MatchFilterParams('title', 'test'); // field, value
$matchFilter = new MatchFilter($params, [$this->langCode]); // params, languages to search

// 5. Match phrase filter
$params = new MatchFilterParams('title', 'test'); // field, value
$matchPhraseFilter = new MatchPhraseFilter($params, [$this->langCode]); // params, languages to search

Applying few filters

To apply few filters for one request SearchFilter should be used.

// Create indexes filter for elasticsearch
$index = new ElasticSearchIndexFilter(new IndexFilterParams([Product::class, Document::class, Page::class]));
$searchFilter = new SearchFilter()->index([$index]) // select index
                                  ->elements([$matchFilter, $termsFilter, ...]); // add filters

$all = $client->elastichSearch()->filter($searchFilter)->all(); // use filters

Filters intersection

For example, there are few filters:

$index = new ElasticSearchIndexFilter(new IndexFilterParams([Product::class, Document::class, Page::class]));
$brandTerm = new TermsFilter(new TermsFilterParams('brandId', [333, 50]));
$attrTerm = new TermsFilter(new AttributeFilterParams(7, [279, 554]));
$priceTerm = new TermsFilter(new TermsFilterParams('price', [6600]));
$searchFilter = new SearchFilter()->index([$index])
                                  ->elements([$brandTerm , $attrTerm , $priceTerm]);
$all = $client->elastichSearch()
              ->filter($searchFilter)
              ->all();

List of this filters will be applied as:

WHERE
(brandId = 333 AND (attributeId = 7 AND attributeValueId = 279) AND price = 6600)
OR
(brandId = 333 AND (attributeId = 7 AND attributeValueId = 554) AND price = 6600)
OR
(brandId = 50 AND (attributeId = 7 AND attributeValueId = 279) AND price = 6600)
OR
(brandId = 50 AND (attributeId = 7 AND attributeValueId = 554) AND price = 6600)

Full text search

// Create elasticsaerch instance
$elasticSearch = $client->elasticSearch();

// Create indexes filter for elasticsearch
$index = new ElasticSearchIndexFilter(new IndexFilterParams([Product::class, Document::class, Page::class]));

// Create full text filter with index filter inside
$filter = (new FullTextFilter())->index([$index])->keyword('test');

// Apply filter and get result from elasticsearch
$elasticSearch->filter($filter)->all();

// Selecting fields to search
// By default: title, shortDescription, fullDescription
$elasticSearch->filter($filter)
              ->fields(new FullTextSearchFieldsParams(['title', 'shortDescription']))
              ->all();

Sorting param types

// 1. Sorting params for entity fields
$sort = new FieldSortParams(string $field, string $order = 'asc');

// 2. Sorting params for attributes
$sort = new AttributeSortParams(int $attributeId, string $order = 'asc');

Using sorting

$elasticSearch = $client->elasticSearch();
$index = new ElasticSearchIndexFilter(new IndexFilterParams([Product::class, Document::class, Page::class]));
$filter = (new FullTextFilter())->index([$index])->keyword('test');

$allWithPriceSort = $elasticSearch->filter($filter)
                                  ->sort(new FieldSortParams('price')) // sorting by price field
                                  ->all();

$allWithAttributeSort = $elasticSearch->filter($filter)
                                      ->sort(new AttributeSortParams(7)) // sorting by attribute with id 7, attributeValueOrderNumber field
                                      ->all();

Faceted search

To apply few filters for one request SearchFilter should be used.

// Create indexes filter for elasticsearch
$index = new ElasticSearchIndexFilter(new IndexFilterParams([Product::class, Document::class, Page::class]));

// 1. Filter for using terms for faceted by brandId
$brandFilter = new TermsFilter(new TermsFilterParams('brandId', [333, 50])));
// 2. Filter for using terms for faceted by attribute
$attributeFilter = new TermsFilter(new AttributeFilterParams('7', [301, 302])));

$searchFilter = new SearchFilter()->index([$index]) // select index
                                  ->elements([$brandFilter, $attributeFilter, ...]); // add filters

$facets = $client->elastichSearch()->filter($searchFilter)->facets(); // use filters

Geo search (by radius)

// Create indexes filter for elasticsearch
$index = new ElasticSearchIndexFilter(new IndexFilterParams([Dealer::class]));
// 1. Filter for using terms for GeoFilter for Dealers
$dealersGeo = new DealersGeoFilter(new DealersGeoFilterParams(200, 40, -70, GeoDistanceUnits::KILOMETER));
// 2.Create geo filter
$searchFilter = (new SearchFilter())->index([$index])// select index
                                          ->elements([$dealersGeo]);
// 3. Apply filter and get result from elasticsearch
$result = $this->client->elasticSearch()->filter($searchFilter)->all();