【问题标题】:Elasticsearch : Problem with querying document where "." is included in fieldElasticsearch:查询“。”的文档时出现问题。包含在字段中
【发布时间】:2020-10-03 15:12:35
【问题描述】:

我有一个索引,其中一些条目类似于

{
    "name" : " Stefan Drumm"
}
...
{
    "name" : "Dr. med. Elisabeth Bauer"
}

name字段的映射是

{
  "name": {
    "type": "text",
    "analyzer": "index_name_analyzer",
    "search_analyzer": "search_cross_fields_analyzer"
  }
}

当我使用以下查询时

GET my_index/_search
  {"size":10,"query":
   {"bool":
    {"must":
     [{"match":{"name":{"query":"Stefan Drumm","operator":"AND"}}}]
,"boost":1.0}},
"min_score":0.0}

它返回第一个文档。

但是当我尝试使用下面的查询获取第二个文档时

GET my_index/_search
  {"size":10,"query":
   {"bool":
    {"must":
     [{"match":{"name":{"query":"Dr. med. Elisabeth Bauer","operator":"AND"}}}]
,"boost":1.0}},
"min_score":0.0}

它没有返回任何东西。

我不能做的事

  1. 无法更改索引
  2. 无法使用术语查询。
  3. 将运算符更改为“OR”,因为在这种情况下它将返回多个条目,这是我不想要的。

我做错了什么以及如何通过修改查询来实现这一点?

【问题讨论】:

  • 你能显示name字段的映射吗?
  • "name": { "type": "text", "analyzer": "index_name_analyzer", "search_analyzer": "search_cross_fields_analyzer" }
  • 如果你有一个keyword 子字段,它会很容易使用,因为你似乎在做完全匹配。但是,如果您无法更改映射并且不想使用术语查询,我不确定您如何继续,就像说,我的轮胎瘪了,我想继续快速行驶但我不不想改变它...
  • 我明白你的意思。但是既然分析器已经到位,那么使用术语查询没有意义吧?
  • 这无关。您似乎在进行精确搜索,那么分析器的意义何在?他们是做什么的?

标签: elasticsearch


【解决方案1】:

您为索引和搜索配置了不同的分析器(index_name_analyzersearch_cross_fields_analyzer)。如果这些分析器以不兼容的方式处理输入 Dr. med. Elisabeth Bauer,则搜索不会匹配。这在Index and search analysisControlling Analysis 中有更详细的描述。

您没有提供这两个分析器的定义,因此很难从您的问题中猜出它们在做什么。根据分析器的不同,可以在执行搜索之前预处理您的查询字符串(例如,通过删除 .),以便搜索匹配。

您可以使用_analyze API 调查分析如何影响您的搜索,如Testing analyzers 中所述。对于您的示例,命令

GET my_index/_analyze
{
  "analyzer": "index_name_analyzer", 
  "text":     "Dr. med. Elisabeth Bauer"
}

GET my_index/_analyze
{
  "analyzer": "search_cross_fields_analyzer", 
  "text":     "Dr. med. Elisabeth Bauer"
}

应该向您展示为您的索引配置的两个分析器如何处理目标字符串,这可能会为您提供有关问题所在的线索。响应将类似于

{
  "tokens": [
    {
      "token": "dr",
      "start_offset": 0,
      "end_offset": 2,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "med",
      "start_offset": 4,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "elisabeth",
      "start_offset": 9,
      "end_offset": 18,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "bauer",
      "start_offset": 19,
      "end_offset": 24,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}  

对于上面的示例输出,分析器已将输入拆分为每个单词一个标记,将每个单词小写,并丢弃所有标点符号。

我的猜测是 index_name_analyzer 保留标点符号,而 search_cross_fields_analyzer 丢弃它,因此标记将不匹配。如果是这种情况,并且您无法更改索引配置(正如您在问题中所述),另一种选择是在运行查询时指定不同的分析器:

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": {
              "query": "Dr. med. Elisabeth Bauer",
              "operator": "AND",
              "analyzer": "index_name_analyzer"
            }
          }
        }
      ],
      "boost": 1
    }
  },
  "min_score": 0
}

在上面的查询中,analyzer 参数已设置为覆盖搜索分析,以使用与索引时使用的分析器相同的分析器 (index_name_analyzer)。使用哪种分析器可能有意义取决于您的设置。理想情况下,您应该将分析器配置为对齐,这样您就不必在搜索时进行覆盖,但听起来您并没有生活在一个理想的世界中。

【讨论】:

  • 我明白你的意思。但由于隐私问题,我无法共享分析器。我很想知道可能的解决方案。如果我像 GET my_index/_search {"size":10,"query": {"bool": {"must": [{"match":{"name":{"query":"Dr med Elisabeth Bauer","operator":"AND"}}}] ,"boost":1.0}}, "min_score":0.0} 这样进行查询,那就是删除“。”从查询中,它什么也不返回。
  • @fellow_dev 分析器本身过于敏感,无法在 Stack Overflow 上分享,这听起来很奇怪。无论如何,我已经扩展了我的答案,以描述您如何自己测试分析器并查看它们每个将如何处理您的输入。
  • 我扩展了我的答案,还描述了如何覆盖搜索分析器。
  • 你是绝对正确的。 search_cross_fields_analyzer 的行为与您展示的完全一样。 index_name_analyzer 配置了停用词,因此 Drmed 被丢弃。但是将查询更改为GET my_index/_search { "query": { "bool": { "must": [ { "match": { "name": { "query": "dr med elisabeth bauer", "operator": "AND", "analyzer": "search_cross_fields_analyzer" } } } ], "boost": 1 } }, "min_score": 0 } - 仍然没有结果。为什么?
  • 设置"analyzer": "search_cross_fields_analyzer" 无效,因为这已经是索引的默认搜索分析器,正如索引设置中的search_analyzer 参数所指定的那样。 search_cross_fields_analyzer 不起作用的原因是它生成标记 drmedelisabethbauer 并要求所有这些标记都存在于文档中(由于 AND 运算符)。但是index_name_analyzerdrmed 丢弃为停用词,这意味着这两个标记将永远出现在文档中,因此搜索无法匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-17
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-03-09
  • 2014-02-12
  • 2016-04-23
相关资源
最近更新 更多