如何在 elasticsearch 中查询单词的替代拼写和表示?

How to query for alternative spellings and representations of words in elasticsearch?

我正在使用 elasticsearch 查询文档中的 theme 字段。例如:

[
  { theme: 'landcover' },
  { theme: 'land cover' },
  { theme: 'land-cover' },
  etc
]

我想指定与所有这些文档匹配的术语 landcover 的搜索。我该怎么做?

到目前为止,我已经尝试在 match 搜索和模糊查询中使用模糊运算符。然而,这两种方法似乎都不起作用,这让我感到惊讶,因为我对模糊搜索的理解是它们会提供一种不精确匹配的方法。

我错过了什么?从文档中我看到模糊性肯定会寻找与搜索词的近似值:

When querying text or keyword fields, fuzziness is interpreted as a Levenshtein Edit Distance — the number of one character changes that need to be made to one string to make it the same as another string.

我认为 'landcover' 和 'land cover' 接近。不是这样吗? (这是我第一次听说 Levenshtein Edit Distance,所以我不知道 extra/less 个字符在这个测量方面的含义)。

这似乎不起作用的匹配查询示例:

{
  query: {
    match: {
      'theme': {
        query: 'landcover'
        fuzziness: 'AUTO' // I've tried 2, '2', 6, '6', etc.
      },
    },
  },
}

// When the term is 'land-cover' and fuzziness is auto, then 'land cover' is matched. But 'landcover' is not

以及一个似乎不起作用的 'fuzzy' 查询示例:

{
  query: {
    fuzzy: {
      'theme': {
        value: query,
        fuzziness: 'AUTO', // Tried other values
      },
    },
  },
}

// When the term is 'land-cover' and fuzziness is auto, then 'landcover' is matched. But 'land cover' is not. So works almost opposite to the match query in this regard

(注意 - 这些查询被转换为 JSON 并执行 运行 和 return 合理的结果,只是模糊性似乎没有像我预期的那样工作)

环顾 Whosebug,我看到一些问题似乎表明查询索引在某种程度上与索引的创建方式相关 - 即我不能只 运行 对已经存在的任何索引进行临时查询存在并期待结果。这个对吗? (抱歉 - 我是 elasticsearch 的新手,我正在查询一个已经存在的索引)。

这个答案似乎相关(如何找到搜索词的近似匹配项): - 提到我应该在索引数据之前做一些被称为 'field mapping' 的事情。但是示例查询不包含 fuzziness 运算符。所以在这种情况下,我对模糊运算符的实际意义感到困惑。

仔细查看文档,我发现了以下内容:

Elasticsearch 使用 'index' 而不是数据库的概念。但是从熟悉 CouchDB 和 MongoDB 的人的角度来看,它们都是 JSON 存储,CouchDB 数据库和 Elasticsearch 索引之间肯定有一些相似之处。虽然elasticsearch索引本身并不是一个权威的数据存储(它是'built'来自一个数据源)

对于给定的索引,例如 my-index。您可以通过 PUT 将 JSON 字符串(文档)插入到 my-index 到 Elasticsearch:

PUT /... '{... json string ...}'

JSON 字符串可以直接来自 JSON 商店(Mongo、Couch 等),也可以从各种来源拼凑而成。我猜。

Elasticsearch 将在插入和追加到倒排树时处理文档。对于文本字段,这意味着 K:V 对将从 JSON 文档文本创建,键是文本片段,值是对在源中找到该文本片段的位置的引用(JSON文档)。

换句话说,当向 Elasticsearch 索引中插入文档时,内容是 'analyzed' 以创建 K:V 对添加到索引中。

那么,我想搜索 Elasticsearch 意味着查找作为索引中键的搜索词,并将值(键的来源)与搜索中定义的来源(我认为)进行比较,然后返回存在特定字段的搜索词的源文档。

所以:

  1. 插入索引时分析文本
  2. 查询被分析(使用与创建索引相同的分析器)

所以在我的例子中(如上所述)默认分析器足以创建允许基本模糊匹配的索引(即在匹配查询中,"land-cover" 匹配到 "land cover",在模糊查询中,"land-cover" 匹配到 "landcover" - 我不知道为什么它们匹配不同!)

但是为了改进搜索结果,我认为我需要在将文档插入索引时以及在解析查询以应用于索引时调整分析器/分词器。

我对analysis/tokenization的理解是,这是从源文档构建倒排索引的配置。即定义倒排索引的键是什么。据我所知,搜索索引没有什么神奇之处。搜索词必须与倒排索引中的键匹配,否则将没有结果。

我仍然不确定在这种情况下模糊性到底在做什么。

简而言之,查询 elasticsearch 似乎需要 'holistic perspective' 了解源数据的索引方式和查询的设计方式。

不过,作为免责声明,我在 elasticsearch 经验不足一天的情况下并不是这个问题的权威答案,所以更好的答案将不胜感激!