返回

更简单、更强大:如何将精确搜索与 Elasticsearch 词干混合?

后端

在构建搜索应用程序时,词干提取通常是必须的,因为希望 skiing 查询匹配包含 ski 或 skis 的文档。 但是如果用户想专门搜索 skiing 怎么办? 执行此操作的典型方法是使用 multi-field 查询,其中一个字段使用精确搜索,另一个字段使用词干。

但是,这可能会导致问题。 考虑以下查询:

(滑雪或滑雪板)并且(滑雪场或滑雪胜地)

此查询将匹配包含以下项的文档:

  • “滑雪场”和“滑雪”
  • “滑雪场”和“滑雪板”
  • “滑雪胜地”和“滑雪”
  • “滑雪胜地”和“滑雪板”

但是,它不会匹配包含以下项的文档:

  • “滑雪”和“滑雪胜地”
  • “滑雪板”和“滑雪场”

这是因为 Elasticsearch 将该查询解析为:

(滑雪或滑雪板)和(滑雪场或滑雪胜地)

而不是:

(滑雪和滑雪场)或(滑雪板和滑雪胜地)

为了使查询按预期工作,您需要使用 nested 查询:

{
  “nested”: {
    “path”: “fields”,
    “query”: {
      “bool”: {
        “should”: [
          {
            “term”: {
              “fields.field1”: “滑雪”
            }
          },
          {
            “term”: {
              “fields.field1”: “滑雪板”
            }
          }
        ]
      }
    }
  }
}

此查询将匹配包含以下项的文档:

  • “滑雪场”和“滑雪”
  • “滑雪场”和“滑雪板”
  • “滑雪胜地”和“滑雪”
  • “滑雪胜地”和“滑雪板”

以及以下项:

  • “滑雪”和“滑雪胜地”
  • “滑雪板”和“滑雪场”

但是,nested 查询可能很慢,尤其是在您处理大量数据时。

一种更有效的方法是使用自定义分析器。 自定义分析器允许您定义自己的词干规则。 您可以使用这些规则来确保某些术语始终匹配精确搜索,而其他术语则使用词干。

例如,您可以创建一个自定义分析器,将滑雪和滑雪板标记为保留术语。 这意味着这些术语将始终匹配精确搜索,即使它们被词干化。

要创建自定义分析器,请按照以下步骤操作:

  1. 打开 Elasticsearch 控制台。
  2. 单击“索引”选项卡。
  3. 单击要向其添加自定义分析器的索引的名称。
  4. 单击“分析”选项卡。
  5. 单击“创建分析器”按钮。
  6. 在“名称”字段中,输入自定义分析器的名称。
  7. 在“类型”字段中,选择“自定义”。
  8. 在“字符过滤器”字段中,选择要使用的字符过滤器。
  9. 在“词法分析器”字段中,选择要使用的词法分析器。
  10. 在“保留术语”字段中,输入要标记为保留术语的术语列表。
  11. 单击“创建”按钮。

创建自定义分析器后,您需要将其应用于要使用它的字段。 为此,请按照以下步骤操作:

  1. 打开 Elasticsearch 控制台。
  2. 单击“索引”选项卡。
  3. 单击要向其添加自定义分析器的索引的名称。
  4. 单击“映射”选项卡。
  5. 单击要应用自定义分析器的字段的名称。
  6. 在“分析器”字段中,选择要使用的自定义分析器。
  7. 单击“保存”按钮。

现在,您已经将自定义分析器应用于字段,您可以使用它来执行精确搜索。 为此,请在查询中使用 term 查询。 例如,要搜索包含 skiing 一词的文档,可以使用以下查询:

{
  “term”: {
    “field1”: “skiing”
  }
}

此查询将仅匹配包含 skiing 一词的文档,即使该词被词干化。

将精确搜索与 Elasticsearch 词干相结合可以帮助您创建更强大、更灵活的搜索应用程序。 通过遵循本指南,您可以学习如何执行此操作。