【问题标题】:Fuzzy Matching Fails But Exact Match Passes模糊匹配失败但精确匹配通过
【发布时间】:2018-10-23 15:28:11
【问题描述】:

我一直在使用模糊匹配构建 ElasticSearch 查询来匹配系统中的用户。当针对特定的用户组(我的名字的用户)运行它时,查询似乎运行良好,但是当针对随机选择的用户运行它时,它似乎失败了。

出于测试目的,我传递的是特定用户的确切值,因此我预计至少有 1 个匹配项。

在缩小范围时,我发现exact 与名称匹配会按预期返回数据,但将 same 值放入模糊块会导致它返回 0 个结果。

例如,此查询按预期返回用户记录:

{
    "from": 0,
    "size": 1,
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "firstName": {
                            "query": "sVxGBCkPYZ",
                            "boost": 30
                        }
                    }
                }
            ],
            "should": [

            ]
        }
    },
    "fields": [
        "id",
        "firstName"
    ]
}

但是,用以下内容替换 match 元素无法返回任何记录:

{
    "fuzzy": {
        "firstName": {
            "value": "sVxGBCkPYZ",
            "fuzziness": 2,
            "boost": 30,
            "min_similarity": 0.3
        }
    }
}

为什么会发生这种情况,我能做些什么来纠正这种情况?

供参考。这是我目前使用的 ES 版本:

"version": {
    "number": "1.7.1",
    "build_hash": "b88f43fc40b0bcd7f173a1f9ee2e97816de80b19",
    "build_timestamp": "2015-07-29T09:54:16Z",
    "build_snapshot": false,
    "lucene_version": "4.10.4"
}

【问题讨论】:

  • 查询 firstName 和 personal.firstName 不应该相同。你能发布你的映射吗?获取 /_mapping ?
  • @Lupanoide 道歉,我错过了该示例的一些代码清理。它们是同一个字段。

标签: elasticsearch fuzzy-search


【解决方案1】:

匹配失败,因为fuzzy searchesterm level queries,这意味着查询字符串将不被分析,而我假设如果数据类型为textstandard analyzer,则已编入索引,将在倒排索引中转换为 svxgbckpyz

您可以改为使用match 查询实现fuzziness,如下所示:

POST testindex/_search
{  
   "query":{  
      "match":{  
         "firstname":{  
            "query":"sVxGBCkPYZ",
            "fuzziness":"AUTO"
         }
      }
   }
}

您可以根据您的用例将值从 AUTO 更改为 23

您提到的exact 匹配也有效,因为查询字符串将被分析并将输入字符串转换为小写,这在倒排索引中可用。

至于模糊查询(你提到的)在幕后是如何工作的,根据这个LINK,如下:

模糊查询通过获取原始术语并构建一个 Levenshtein 自动机——就像一个代表所有字符串的大图 在原始字符串的指定编辑距离内。

然后模糊查询使用自动机高效地单步执行 术语字典中的所有术语,以查看它们是否匹配。一旦它 已收集该术语中存在的所有匹配术语 字典,它可以计算匹配文档的列表。

当然,根据存储在索引中的数据类型,一个模糊的 编辑距离为 2 的查询可以匹配非常多的 条款和表现非常糟糕。

特别注意这个声明,representing all the strings that are within the specified edit distance of the original string

例如life 的一些距离为 1 的单词将是 aife, bife, cife, dife....lifz

因此,在您的情况下,模糊搜索的自动机首先无法从输入字符串 sVxGBCkPYZ 创建术语 svxgbckpyz,因为它们之间的距离为 7(请记住,Aa 之间的距离为 1)我不认为AUTO 选项可以创建,即使您将其配置为7,它也可能无法创建字符串,因为会有大量距离7 的单词

再添加一个LINK 以获取更多信息。希望能帮助到你!

【讨论】:

  • 那么,如果我在查询中转换为小写字母会改善问题吗?我使用模糊的原因是为了能够指定阈值和权重(完整的查询有多个模糊查询),不过最好将其作为一个不同的问题。
  • @ObsidianPhoenix 哦,是的!当然!!将您的输入字符串转换为小写也是一种选择。我应该提到它,但很抱歉我按原样继续输入字符串。另请注意,如果您使用我提到的解决方案,我认为不会有那么大的变化,因为它还允许您指定阈值和提升。只是,fuzzy 使用 match 可以保护您在搜索期间使用与索引期间使用的分析器相同的分析器。
猜你喜欢
  • 2018-06-09
  • 1970-01-01
  • 2012-04-30
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
相关资源
最近更新 更多