首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的术语查询在匹配时不使用弹性查询

简单的术语查询在匹配时不使用弹性查询
EN

Stack Overflow用户
提问于 2018-09-19 18:44:12
回答 2查看 5.6K关注 0票数 7

我有一个JSON对象,如下所示。

代码语言:javascript
复制
{
    "_source" : {
      "version" : 1,
      "object_id" : "f1dcae27-7a6f-4fea-b540-901c09b60a15",
      "object_name" : "testFileName_for_TestSweepAndPrune",
      "object_type" : "",
      "object_status" : "OBJ_DELETED",
      "u_attributes" : ""
    }

}

像这样的术语查询不起作用。

代码语言:javascript
复制
{
            "query": {
                "term": {
                    "object_status": "OBJ_DELETED"
                }
            },
            "size": 10000

}

with查询在相同条件下工作良好。

代码语言:javascript
复制
{
            "query": {
                "match": {
                    "object_status": "OBJ_DELETED"
                }
            },
            "size": 10000

}

想知道这里会发生什么?对于这种情况,我如何使术语查询在这里起作用?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-20 12:17:16

要理解为什么term查询不能像您预期的那样工作,我们需要检查ElasticSearch处理和保存数据的方式,以及matchterm查询是如何不同的。

通常,当您将一些文本保存到ElasticSearch中时,首先会对其进行分析,然后再保存。分析由分析器进行。有许多分析器,但如果您不指定任何一个,那么默认的一个将被使用。Analyzer处理文本,将其转换为令牌数组,并保存令牌列表。对于每个特定的分析器,文本被分割成标记的规则是不同的。

在处理和保存文本时,您可以查询它。查询某事的方法有很多种,但在您的示例中,matchterm的主要区别是match全文查询term术语级查询。问题是,在全文搜索的情况下,您的查询字符串将以与您正在查询的字段相同的方式进行分析。在术语级查询中,不分析查询字符串。值得注意的是。

现在让我们看看"OBJ_DELETED"是如何被ElasticSearch分析的。为此,我们可以添加如下简单文档:

代码语言:javascript
复制
curl -X PUT 'localhost:9200/testdata/object/1' -H 'Content-Type: application/json' -d '{ "object_status": "OBJ_DELETED"  }'

然后检查所有的东西都在那里:

代码语言:javascript
复制
curl -X POST 'localhost:9200/testdata/_search?pretty'

应该产生这样的东西:

代码语言:javascript
复制
...
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
  {
    "_index" : "testdata",
    "_type" : "object",
    "_id" : "1",
    "_score" : 1.0,
    "_source" : {
      "object_status" : "OBJ_DELETED"
    }
  }
]

}

现在我们可以检查"OBJ_DELETED"是如何分析的:

代码语言:javascript
复制
curl -X POST 'localhost:9200/testdata/_analyze?pretty' -H 'Content-Type: application/json' -d '{ "text": "OBJ_DELETED"  }'

它的产出是:

代码语言:javascript
复制
{
  "tokens" : [
    {
      "token" : "obj_deleted",
      "start_offset" : 0,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}

如您所见,它只将文本转换为小写,并将其保存为一个令牌。默认分析器就是这样做的。现在返回您的查询。match查询之所以有效,是因为查询值"OBJ_DELETED"也被转换为掩码下的小写,因此ElasticSearch可以找到它。对于term查询,查询字符串没有处理,因此实际上您正在将OBJ_DELETEDobj_deleted进行比较,显然没有得到任何结果。

最后一个问题:为什么object_status.keyword适用于term查询?

默认情况下,ElasticSearch为每个文本字段创建附加映射。这是一种元数据,你可以使用。此外,它还允许您以不同的方式处理相同的值。因此,默认情况下,每个文本字段都有与名称keyword的附加映射,后者具有关键字类型。不分析keyword字段(只有在需要时才能对它们进行规范化分析)。这意味着对于默认映射,它保存了传递给ElasticSearch (在本例中为OBJ_DELETED)的确切值。

票数 23
EN

Stack Overflow用户

发布于 2020-12-15 11:10:12

您应该避免对term字段使用text查询(参见指南中的术语查询说明)。默认情况下,弹性搜索会在分析期间更改文本字段的值。例如,默认的标准分析器将文本字段值更改如下:

  • 移除大部分标点符号
  • 将剩余的内容分成单独的单词,称为令牌
  • 小写代币

您可以使用关键词分析器从索引中的适当字段生成正确和可搜索的term。Elasticsearch为指定分析器提供了多种方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52412359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档