【问题标题】:Elasticsearch term vs matchElasticsearch 术语与匹配
【发布时间】:2020-09-01 15:27:00
【问题描述】:

我必须在 2 个条件下编写搜索查询。

  1. 时间戳
  2. 目录

当我在下面的搜索查询中使用匹配时

{
   "query":{
      "bool":{
         "must":{
            "match":{
               "directory":"/user/ayush/test/error/"
            }
         },
         "filter":{
            "range":{
               "@timestamp":{
                  "gte":"2020-08-25 01:00:00",
                  "lte":"2020-08-25 01:30:00",
                  "format":"yyyy-MM-dd HH:mm:ss"
               }
            }
         }
      }
   }
}

在过滤结果中,我正在获取带有目录的记录

  1. /user/ayush/test/error/
  2. /user/hive/
  3. /user/

但是当我使用如下术语时

{
   "query":{
      "bool":{
         "must":{
            "term":{
               "directory":"/user/ayush/test/error/"
            }
         },
         "filter":{
            "range":{
               "@timestamp":{
                  "gte":"2020-08-25 01:00:00",
                  "lte":"2020-08-25 01:30:00",
                  "format":"yyyy-MM-dd HH:mm:ss"
               }
            }
         }
      }
   }
}

即使是目录值,我也没有得到任何结果 /user/ayush/test/error/

【问题讨论】:

    标签: elasticsearch elasticsearch-dsl


    【解决方案1】:

    匹配查询分析输入字符串并构造更基本的 查询。

    术语查询匹配确切的术语。

    请参阅这些博客以获取详细信息:

    SO question on Term vs Match query

    https://discuss.elastic.co/t/term-query-vs-match-query/14455

    elasticsearch match vs term query

    字段值/user/ayush/test/error/分析如下:

    POST/_analyze
    {
      "analyzer" : "standard",
      "text" : "/user/ayush/test/error/"
    }
    

    生成的令牌是:

    {
        "tokens": [
            {
                "token": "user",
                "start_offset": 1,
                "end_offset": 5,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
                "token": "ayush",
                "start_offset": 6,
                "end_offset": 11,
                "type": "<ALPHANUM>",
                "position": 1
            },
            {
                "token": "test",
                "start_offset": 12,
                "end_offset": 16,
                "type": "<ALPHANUM>",
                "position": 2
            },
            {
                "token": "error",
                "start_offset": 17,
                "end_offset": 22,
                "type": "<ALPHANUM>",
                "position": 3
            }
        ]
    }
    

    索引数据:

    { "directory":"/user/ayush/test/error/" }
    { "directory":"/user/ayush/" }
    { "directory":"/user" }
    

    使用词条查询的搜索查询:

    词条查询不会对搜索词条应用任何分析器,因此只会在倒排索引中查找准确的词条。所以要搜索确切的词,你需要使用directory.keyword或者改变字段的映射。

    {
      "query": {
        "term": {
          "directory.keyword": {
            "value": "/user/ayush/test/error/",
            "boost": 1.0
          }
        }
      }
    }
    

    词条查询的搜索结果:

    "hits": [
                {
                    "_index": "my_index",
                    "_type": "_doc",
                    "_id": "1",
                    "_score": 0.9808291,
                    "_source": {
                        "directory": "/user/ayush/test/error/"
                    }
                }
            ]
    

    【讨论】:

    • 但是为什么术语查询无法找到目录 /user/ayush/test/error/ ,即使它确实存在? /我需要一些特殊字符吗?
    • @AyushGoyal 如果你想得到你的术语查询的结果,你需要directory.keyword如果它在你的映射中(如果你正在考虑动态映射),否则创建一个keyword字段存储字段值
    • 看来 directory.keyword 是我要找的东西。
    • @AyushGoyal 是的,使用.keyword,您还将获得带有术语查询的搜索结果。
    • @AyushGoyal 如果你能接受并支持我的回答,那就太好了:)
    猜你喜欢
    • 2021-11-11
    • 1970-01-01
    • 2020-07-07
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多