William Paul
William Paul

Reputation: 337

Elasticsearch match all tags within given array

Currently developing a tag search application using elasticsearch, I have given each document within the index an array of tags, here's an example of how a document looks:

_source: {
  title: "Keep in touch scheme",
  intro: "<p>hello this is a test</p> ",
  full: " <p>again this is a test mate</p>",
  media: "",
  link: "/training/keep-in-touch",
  tags: [
    "employee",
    "training"
  ]
}

I would like to be able to make a search and only return documents with all of the specified tags.

Using the above example, if I searched for a document with tags ["employee", "training"] then the above result would be returned.

In contrast, if I searched with tags ["employee", "other"], then nothing would be returned; all tags within the search query must match.

Currently I am doing:

query: {
  bool: {
    must: [
      { match: { tags: ["employee","training"] }}
     ]
   }
 }

but I am just getting returned exceptions like

IllegalStateException[Can't get text on a START_ARRAY at 1:128];

I have also tried concatenating the arrays and using comma-delimited strings, however this seems to match anything given the first tag matches.

Any suggestions on how to approach this? Cheers

Upvotes: 5

Views: 5069

Answers (2)

cn0047
cn0047

Reputation: 17091

Option 1: Next example should work (v2.3.2):

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
  "query": {
    "bool": {
      "must": [
        { "term": { "tags": "employee" } } ,
        { "term": { "tags": "training" } }
      ]
    }
  }
}'

Option 2: Also you can try:

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
  "query": {
    "filtered": {
      "query": {"match_all": {}},
      "filter": {
        "terms": {
          "tags": ["employee", "training"]
        }
      }
    }
  }
}'

But without "minimum_should_match": 1 it works little bin not accurate. I also found "execution": "and" but it works not accurate too.

Option 3: Also you cat try query_string it works perfectly, but looks little bit complicated:

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
"query" : {
    "query_string": {
      "query": "(tags:employee AND tags:training)"
    }
  }
}'

Maybe it will be helpful for you...

Upvotes: 1

moyukh bera
moyukh bera

Reputation: 124

To ensure that the set contains only the specified values, maintain a secondary field to keep track of the tags count. Then you can query like below to get the desired results

"query":{
   "bool":{
        "must":[
             {"term": {"tags": "employee"}},
             {"term": {"tags": "training"}},
             {"term": {"tag_count": 2}}
        ]  
   }
}

Upvotes: 0

Related Questions