pharkasbence
pharkasbence

Reputation: 987

Elasticsearch: find exact match in array

I have the following documents:

{
    ...
    _source: {
        id: 1, 
        tags: [
            "xxx"
        ]
    }
},
{
     ...
     _source: {
         id: 2, 
         tags: [
             "xxx yyy"
         ]
     }
}

How can I search for "xxx" if I would like to retrieve only the first document?

I tried this:

"query" : {
    "filter" : {
        "term" : { 
           "tags" : "xxx"
        }
    }
}

But it returned with both documents.

Upvotes: 3

Views: 1442

Answers (1)

cinhtau
cinhtau

Reputation: 1042

Your basic problem is, you haven't defined an explicit mapping, so the default mapping will come into play. Assuming you are working on the latest version 5 or 6.

Searching in the tags field is analyzed text, thus it will create for xxx yyythe tokens xxxand yyywhich matches also your search.

GET _analyze
{
  "text": "xxx yyy"
}

You could query for the multi-field tags.keyword that will give you an exact match (field value is not analyzed). For instance:

GET _search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "tags.keyword": "xxx"
        }
      }
    }
  }
}

Or another possibility, and doing it right from the start, use the keyword type only. tags tend in general to be of type keyword or not analyzed.

Define a mapping

PUT test
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "doc": {
      "properties": {
        "tags": {
          "type": "keyword"
        }
      }
    }
  }
}

PUT test/doc/1
{
  "tags": [
    "xxx"
  ]
}
PUT test/doc/2
{
  "tags": [
    "xxx yyy"
  ]
}

Using the above mapping, you can search for tags then.

Upvotes: 2

Related Questions