匹配和术语在文本字段elasticsearch上给出不同的结果

Bha*_*wan 0 elasticsearch

我正在学习 elasticsearch-7.4.0 并使用基本查询。

我有一个product索引,其中有一个name具有以下映射的字段:

"name" : {
  "type" : "text",
  "fields" : {
    "keyword" : {
      "type" : "keyword",
      "ignore_above" : 256
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我执行术语查询来匹配名称为“ Wine - Ice Wine”的文档时。

GET /product/_search
{
  "from": 0,
  "size" : 1000,
  "query": {
    "term": {
      "name": {
        "value": "Wine - Ice Wine"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
Run Code Online (Sandbox Code Playgroud)

当我运行匹配查询时:

GET /product/_search
{
  "from": 0,
  "size" : 1000,
  "query": {
    "match": {
      "name": "Wine - Ice Wine"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 75,
      "relation" : "eq"
    },
    "max_score" : 12.354952,
    "hits" : [
      {
        "_index" : "product",
        "_type" : "doc",
        "_id" : "403",
        "_score" : 12.354952,
        "_source" : {
          "name" : "Wine - Ice Wine",
          "price" : 127,
          "in_stock" : 26,
          "sold" : 334,
          "tags" : [
            "Alcohol",
            "Wine"
          ],
          "description" : "Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh. Quisque id justo sit amet sapien dignissim vestibulum.",
          "is_active" : true,
          "created" : "2010/04/12"
        }
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

如前所述,术语级别查询寻找完全匹配。
因此,我在搜索查询中指定整个字符串。
两个查询应该返回相同的结果。

Kam*_*mal 5

术语查询将用于关键字字段以获得精确匹配。

从上面的链接,我们有以下keyword数据类型:

它们通常用于过滤(查找所有已发布状态的博客文章)、排序和聚合。关键字字段只能按其确切值进行搜索。

从您的映射来看,该字段name有同级字段,name.keyword其类型为keyword

修改您的术语查询以按如下方式使用它,它将为您提供所需的结果。

GET /product/_search
{
  "from": 0,
  "size" : 1000,
  "query": {
    "term": {
      "name.keyword": {                  <---- Note this
        "value": "Wine - Ice Wine"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,match您在字段上使用的查询text会经历分析阶段。

基本上,当您有一个文本类型的字段并且当您摄取文档时,它会将句子转换为标记,将它们转换为小写字母,从而存储在倒排索引中。这将是索引时间分析

当您使用匹配查询时,也会发生同样的事情,即无论您在查询部分中添加什么,它都会分解为单个单词或标记,并在倒排索引中搜索它们。这是搜索时间分析

分析是通过称为“分析器”的概念完成的。默认情况下,它使用标准分析器

我建议您浏览链接以了解更多信息。

希望这可以帮助!