简体   繁体   中英

Elasticsearch - value in array filter

I want to filter out all documents which contain a specific value in an array field. Ie the value is an element of that array field.

To be specific - I want to select all documents which names contains test-name , see the example below.


So when I do an empty search with

curl -XGET localhost:9200/test-index/_search

the result is

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 50,
    "max_score": 1,
    "hits": [
      {
        "_index": "test-index",
        "_type": "test",
        "_id": "34873ae4-f394-42ec-b2fc-41736e053c69",
        "_score": 1,
        "_source": {
          "names": [
            "test-name"
          ],
          "age": 100,
          ...
        }
      },
      ...
   }
}


But in case of a more specific query

curl -XPOST localhost:9200/test-index/_search -d '{
  "query": {
    "bool": {
      "must": {
        "match_all": {}

      },
      "filter": {
        "term": {
           "names": "test-name"
        }
      }
    }
  }
}'

I don't get any results

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


There are some questions similar to this one. Although, I cannot get any of the answers to work for me.

System specs: Elasticsearch 5.1.1 , Ubuntu 16.04


EDIT

curl -XGET localhost:9200/test-index
          ...
          "names": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          ...

That's because the names field is analyzed and test name gets indexed as two tokens test and name .

Searching for the test name term will hence not yield anything. If you use match instead, you'll get the document.

If you want to check for the exact value test name (ie the two tokens one after another), then you need to change your names field to a keyword type instead of text

UPDATE

According to your mapping, the names field is analyzed, you need to use the names.keyword field instead and it will work, like this:

curl -XPOST localhost:9200/test-index/_search -d '{
  "query": {
    "bool": {
      "must": {
        "match_all": {}

      },
      "filter": {
        "term": {
           "names.keyword": "test-name"
        }
      }
    }
  }
}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM