ArGh
ArGh

Reputation: 1168

FOSElasticaBundle : Query matching combinaison of values

I need some help to make my elasticsearch query fully working (using version 6.8.5).
I have a list of ES objects stored in my index :

Object 1:  
    name: abcd
    type: A
    tags: Tag one, Tag two

Object 2:
    name: abcdef
    type: B 
    tags: Tag three

Object 3: 
    name: cdef
    type: B
    tags: Tag one, Tag three

Object 4: 
    name: abcd efgh
    type: C
    tags: Tag one, Tag three

Object 5: 
    name: efghbc
    type: A
    tags: Tag three

I need to query :

Object.name MUST contain "bc"
AND
Object.type MUST be (A OR C)
AND
Object.tags MUST have (tag1 OR tag3)

So my results shoud give me :

Object 1 : match "bc" AND A type AND "tag one"
Object 4 : match "bc" AND C type AND ("tag one" AND "tag three")
Object 5 : match "bc" AND A type AND "tag three"

Here is my PHP code for the moment :


$boolQuery = new \Elastica\Query\BoolQuery();

// ex : $q = 'bc';

if (!empty($q)) {
    $fieldQuery = new \Elastica\Query\MatchPhrasePrefix();
    $fieldQuery->setFieldQuery('name', $q);
    $fieldQuery->setFieldParam('name', 'analyzer', 'ngram_analyzer');
    $boolQuery->addShould($fieldQuery);
} else {
     $fieldQuery = new \Elastica\Query\MatchAll();
     $boolQuery->addMust($fieldQuery);
}

$subQuery = new \Elastica\Query\BoolQuery();

$typeQuery = new \Elastica\Query\Terms();
$typeQuery->setTerms('type', ['A', 'C']);
$subQuery->addMust($typeQuery);

$filterQuery = new \Elastica\Query\Terms();
$filterQuery->setTerms('tags', ['Tag one', 'Tag three']);
$subQuery->addMust($filterQuery);

$boolQuery->addMust($subQuery);
$query = new \Elastica\Query($boolQuery);

My results are always null. If I remove the filterQuery, I have my results corresponding to :

Object 1 : match "bc" AND A type
Object 4 : match "bc" AND C type
Object 5 : match "bc" AND A type

I also tried to isolate the filterQuery in another Boolean Query without any result. Thanks !!

Upvotes: 0

Views: 358

Answers (1)

ArGh
ArGh

Reputation: 1168

I finally found a working code. I had to replace this part

$filterQuery = new \Elastica\Query\Terms();
$filterQuery->setTerms('tags', ['Tag one', 'Tag three']);
$subQuery->addMust($filterQuery);

by this one

$tagFilters = ['Tag one', 'Tag three'];

$boolFilteredQuery = new \Elastica\Query\BoolQuery();
foreach($tagFilters as $tagFilter){
    $filterQuery = new \Elastica\Query\Match();
    $filterQuery->setFieldQuery('tags', $tagFilter);
    $boolFilteredQuery->addShould($filterQuery);
}
$boolQuery->addMust($boolFilteredQuery);

if someone has an explanation, I'm interested.
Thanks

Upvotes: 0

Related Questions