【问题标题】:How to do an exact match query in ElasticSearch?如何在 ElasticSearch 中进行完全匹配查询?
【发布时间】:2020-03-19 14:52:52
【问题描述】:

我想对 ElasticSearch 索引进行完全匹配查询,
我有以下数据 -

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.21110919,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.21110919,
        "_source" : {
          "id" : 1,
          "name" : "test"
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.160443,
        "_source" : {
          "id" : 2,
          "name" : "test two"
        }
      }
    ]
  }
}

我要查询字段name,
我正在尝试搜索名称test,
但它会将两份文件都返回给我。

预期结果是唯一的文档1
映射如下-

{
  "test" : {
    "mappings" : {
      "properties" : {
        "id" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

我尝试了以下 -

GET /test/_search
{
  "query": {
    "bool": {
      "must": {
        "term" : { 
          "name": "test"
        }
      }
    }
  }
}


GET /test/_search
{
  "query": {
    "match": {
      "name": "test"
    }
  }
}

【问题讨论】:

  • 请添加映射
  • 另外this 回答可能会有所帮助。
  • @OpsterESNinjaNishant 添加了索引映射
  • 在下面查看我的答案,上面评论中的回答链接有详细解释

标签: elasticsearch


【解决方案1】:

除了我在评论中提供的答案的链接之外,我建议您将名称字段定义为:

{
   "name":{
      "type": "text",
      "fields":{
         "keyword":{
            "type": "keyword"
         }
      }
   }
}

然后在您需要完全匹配(区分大小写)时查询字段name.keyword,如果您想要部分匹配(例如仅搜索名字)则查询name

【讨论】:

    【解决方案2】:

    看起来您在 name 字段上使用了 text 数据类型,该数据类型将 test two 在 2 个标记中作为 testtwo 吐出,因此它与您的搜索查询 test 匹配分析match 查询并将相同的分析器应用于结果标记与倒排索引中存在的文档标记匹配。

    解决您的使用示例

    索引定义

    {
      "mappings": {
        "properties": {
          "name": {
            "type": "keyword" --> note use of `keyword` type
          }
        }
      }
    }
    

    索引您的示例文档

    {
       "name" : "test two"
    }
    
    {
       "name" : "test"
    }
    

    搜索查询与您的相同

    {
        "query": {
            "match": {
                "name": "test"
            }
        }
    }
    

    根据需要搜索结果

    "hits": [
             {
                "_index": "so_key",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.6931471,
                "_source": {
                   "name": "test"
                }
             }
          ]
    

    重要提示:您可以使用analyze API查看您的数据是如何被索引的,例如

    在文本字段上使用标准(默认分析器)

    POST _分析

    {
        "text": "test two",
        "analyzer" : "standard" --> Change analyzer to keyword and see diff
    }
    

    代币

    {
        "tokens": [
            {
                "token": "test",
                "start_offset": 0,
                "end_offset": 4,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
                "token": "two",
                "start_offset": 5,
                "end_offset": 8,
                "type": "<ALPHANUM>",
                "position": 1
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 2018-02-18
      • 2014-11-01
      相关资源
      最近更新 更多