【问题标题】:Elasticsearch MatchQuery is returning wrong resultsElasticsearch MatchQuery 返回错误的结果
【发布时间】:2021-03-04 06:30:51
【问题描述】:

我正在使用matchQuery 在 Java 中查询 Elasticsearch。以下是我的查询:

sourceBuilder.query(QueryBuilders.matchQuery("TransactionId_s","BulkRunTest.20Nov20201446.00"));

字段TransactionId_s 不是keyword。我期待 matchQuery 匹配我给出的确切字符串并返回结果。 Elasticsearch 中不应该有 TransactionId_sBulkRunTest.20Nov20201446.00 的文档。但我得到了一些结果,他们有TransactionId_s,如下所示:

"TransactionId_s" : "BulkRunTest.17Sep20201222.00"
"TransactionId_s" : "BulkRunTest.22Sep20201450.00"
"TransactionId_s" : "BulkRunTest.20Sep20201250.00"

当我尝试使用 termQuery 而不是 matchQuery 时,我得到 0 个结果,这是预期的结果。我认为matchQuery 可以让我在任何字段中查询给定值,而不必担心标记化。我错了吗?我该如何解决我看到的问题?

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: java elasticsearch aws-elasticsearch elasticsearch-java-api elasticsearch-7


    【解决方案1】:

    Match 查询被分析,即它应用了在索引时用于字段的相同分析器,您可以analyzer API 并查看索引和搜索词的标记。

    考虑到您有一个带有默认分析器(标准)的 text 字段,它将为搜索词 BulkRunTest.20Nov20201446.00 生成以下标记

    POST /_analyze
    {
        "analyzer" : "standard",
        "text" : "BulkRunTest.20nov20201446.00"
    }
    

    并生成令牌

    {
        "tokens": [
            {
                "token": "bulkruntest", // notice this token
                "start_offset": 0,
                "end_offset": 11,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
                "token": "20nov20201446.00",
                "start_offset": 12,
                "end_offset": 28,
                "type": "<ALPHANUM>",
                "position": 1
            }
        ]
    }
    

    现在让我们看看其中一个匹配文档BulkRunTest.17Sep20201222.00的标记

    POST /_analyze
    {
        "analyzer" : "standard",
        "text" : "BulkRunTest.17Sep20201222.00"
    }
    

    并生成令牌

    {
        "tokens": [
            {
                "token": "bulkruntest", // notice same token 
                "start_offset": 0,
                "end_offset": 11,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
                "token": "17sep20201222.00",
                "start_offset": 12,
                "end_offset": 28,
                "type": "<ALPHANUM>",
                "position": 1
            }
        ]
    }
    

    如您所见,bulkruntest 在索引词和搜索词中是相同的标记,因此匹配查询返回搜索结果,并且与另一个索引文档相同。

    如果您使用默认的自动生成映射并且有.keyword 子字段,那么您可以使用.keyword 字段进行精确搜索。

    工作示例

    {
      "query": {
        "term": {   // term query
          "TransactionId_s.keyword": {   // .keyword subfield is used
            "value": "BulkRunTest.20Nov20201446.00"
          }
        }
      }
    }
    

    以及搜索结果

    "hits": [
                {
                    "_index": "test_in",
                    "_type": "_doc",
                    "_id": "2",
                    "_score": 0.6931471,
                    "_source": {
                        "TransactionId_s": "BulkRunTest.20Nov20201446.00"
                    }
                }
            ]
    

    【讨论】:

    • 感谢您提供非常详细的答案!我最终将该字段定义为关键字,现在它按预期工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 2017-11-14
    • 1970-01-01
    • 2023-03-26
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多