ElasticSearch - match vs term

match vs term

这个问题来自stackoverflow

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

首先还原一下这个场景

创建索引test,含有一个_doc类型

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

索引一个_doc类型的文档到test

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

通过match查找GET,可以找到结果

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

通过term查找GET,找不到结果

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来进行查询时没有任何结果

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

ANSWER

可能使用了Standard Analyzer,在对文档进行索引的时候GET变成了get,而文档的_source依然是GET

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,那么就找不到该文档。

如果想要term查询可以生效,那么可以:

  • 将搜索中的GET变为小写的get
  • 修改request.method字段的类型为not_analyzed
  • 修改request.method字段的类型为keyword

官方文档的一些说明

ElasticSearch官方文档对matchterm的说明

match 接受文本/数字/日期,并分析它们

term 根据提供的确切值查找文本


posted @ 2019-03-21 11:50  大地的谎言  阅读(...)  评论(...编辑  收藏