Mr.Wang from Next Door
Mr.Wang from Next Door

Reputation: 14820

Filter ElasticSearch result whose array contains at least 1 tag

I query against elasticsearch with following DSL.

{
   "query": {
      "filtered": {
         "query": {
            "multi_match": {
               "query": "Next",
               "type": "phrase_prefix",
               "fields": [
                  "defaultContent"
               ]
            }
         },
         "filter": {
            "bool": {
               "must_not": {
                  "term": {
                     "_deleted": true
                  }
               },
               "should": [
                  {
                     "term": {
                        "site": "xxx"
                     }
                  },
                  {
                     "term": {
                        "site": "base"
                     }
                  }
               ]
            }
         }
      }
   }
}

And it works and return 1 match.

{
   "took": 42,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 2.733073,
      "hits": [
         {
            "_index": "cms",
            "_type": "content",
            "_id": "base>3453fm9lxkmyy_17",
            "_score": 2.733073,
            "_source": {
               "tags": [
                  "tag1",
                  "tag2"
               ],
               "site": "base",
               "_rev": "1-3b6eb2b3c3d5554bb3ef3f16a299160c",
               "defaultContent": "Next action to be settled",
               "_id": "base>3453fm9lxkmyy_17",
               "type": "content",
               "key": "3453fm9lxkmyy_17"
            }
         }
      ]
   }
}

Now I want to modify the DSL, and add a new condition -- Only returns those whose tags contains tag1 or tag8

{
   "query": {
      "filtered": {
         "query": {
            "multi_match": {
               "query": "Next",
               "type": "phrase_prefix",
               "fields": [
                  "defaultContent"
               ]
            }
         },
         "filter": {
            "bool": {
               "must": {
                   "term" : {
                       "tags" : ["tag1", "tag8"],
                       "minimum_should_match" : 1
                   }
               },
               "must_not": {
                  "term": {
                     "_deleted": true
                  }
               },
               "should": [
                  {
                     "term": {
                        "site": "xxx"
                     }
                  },
                  {
                     "term": {
                        "site": "base"
                     }
                  }
               ]
            }
         }
      }
   }
}

And then, I get nothing.

{
   "took": 23,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
   }
}

Am I doing something wrong? It should return 1 match because it contains tag1

Upvotes: 0

Views: 1038

Answers (1)

jhilden
jhilden

Reputation: 12449

The "term" filter is used when you want to match on a single term. Kind of like SQL column1 = 'foo'

You want to use the "terms" filter which is the equivalent of SQL column1 IN ('foo', 'bar')

Upvotes: 2

Related Questions