ElasticSearch - match vs term

match vs term

這個問題來自stackoverflowjson

https://stackoverflow.com/questions/23150670/elasticsearch-match-vs-term-queryapp

首先還原一下這個場景

建立索引test,含有一個_doc類型elasticsearch

PUT /test
{
    "mappings" : {
        "_doc" : {
            "properties" : {
                "field1" : {
                    "type" : "text",
                    "analyzer" : "standard"
                }
            }
        }
    }
}

索引一個_doc類型的文檔到testcode

POST /test/_doc
{
    "field1": "GET"
}

經過match查找GET,能夠找到結果索引

GET /test/_doc/_search
{
    "query": {
        "bool": {
            "must": [
                {"match": {"field1": "GET"}}
            ]
        }
    }
}

經過term查找GET,找不到結果token

GET /test/_doc/_search
{
    "query": {
        "bool": {
            "must": [
                {"term": {"field1": "GET"}}
            ]
        }
    }
}

Question

使用match查詢request.method:GET文檔

{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "request.method": "GET"
        }
      },
      "filter": {
        "bool": {
          "must": [
...

match查詢能夠拿到結果,但問題是當使用term來進行查詢時沒有任何結果get

{
  "query": {
    "filtered": {
      "query": {
        "term": {
          "request.method": "GET"
        }
      },
      "filter": {
        "bool": {
          "must": [
...

ANSWER

可能使用了Standard Analyzer,在對文檔進行索引的時候GET變成了get,而文檔的_source依然是GETit

GET /_analyze 
{
  "analyzer": "standard", 
  "text": "GET"
}

# response
# 能夠看到token是get
{
  "tokens": [
    {
      "token": "get",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}

match查詢將會對搜索的句子應用Standard Analyzer,即搜索中的GET會變成get,那麼就會命中文檔。而term查詢並不會對搜索的內容進行分析,所以會直接查找get,那麼就找不到該文檔。io

若是想要term查詢能夠生效,那麼能夠:

  • 將搜索中的GET變爲小寫的get
  • 修改request.method字段的類型爲not_analyzed
  • 修改request.method字段的類型爲keyword

官方文檔的一些說明

ElasticSearch官方文檔對matchterm的說明

match 接受文本/數字/日期,並分析它們

term 根據提供的確切值查找文本