Elasticsearch:如何在 Elasticsearch中 查询相似的术语 (suggest API)

本文探讨了Elasticsearch中的suggester功能,演示了如何在搜索查询中纠正拼写错误,包括术语建议和短语建议API,以及如何使用批量API进行文档索引。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这篇文章中,我们来讲述 Elasticsearch 中的 suggester。通过使用 suggester,根据提供的文本建议外观相似的字词。 建议功能的某些部分仍在开发中。suggester的 官方文档在地址 Suggesters | Elasticsearch Guide [8.6] | Elastic

Term suggestion 功能适用于一下文本编辑软件。在知道该词语是错误的情况下提供一些正确词的候选者。

比如上面的谷歌编辑器或者微软的 WORD 文本编辑器中就会用一个红色的波浪线显示 documnt 是错误的。当我们把鼠标放到改词上面时,它会自动显示一个正确的 document 作为候选的正确的词。

用户经常在搜索查询中犯拼写错误。 即使查询中存在拼写错误,可行的搜索解决方案也必须能够提供建议。 建议 API 提供了两种此类拼写检查 API,即术语建议和短语建议。 术语建议 API 旨在纠正错误键入的单词的拼写。 反过来,短语建议 API 是处理多个术语的,是建议 API 一词的高级版本。 让我们更详细地讨论术语 “建议 API” 及其功能。

测试文档:

我们在 Kibana 中打入如下的 bulk API 命令:

POST _bulk
{ "index" : { "_index" : "term-suggest", "_id": 1 }}
{ "name": "bald"}
{ "index" : { "_index" : "term-suggest", "_id": 2 }}
{ "name": "bold"}
{ "index" : { "_index" : "term-suggest", "_id": 3 }}
{ "name": "blend"}
{ "index" : { "_index" : "term-suggest", "_id": 4 }}
{ "name": "blood"}

这样在我们的 term-suggest 索引中就有四个文档。每个文档含有一个叫做 name 的字段。

用例1 - term suggester

现在索引已包含必要的文档,让我们通过建议查询来演示如何查询拼写错误的单词以及如何显示更正。 将以下建议查询传递给索引:

GET term-suggest/_search
{
  "query": {
    "match": {
      "name": "bold"
    }
  },
  "suggest": {
    "my-suggestion": {
      "text": "bleed",
      "term": {
        "field": "name"
      }
    }
  }
}

请求:

建议功能通过使用建议,根据提供的文本提示外观相似的术语。 建议请求部分在 _search 请求中与查询部分一起定义。 如果查询部分被忽略,则仅返回建议。在上面我们同时使用了 query 及  suggest。显示结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2039728,
    "hits" : [
      {
        "_index" : "term-suggest",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.2039728,
        "_source" : {
          "name" : "bold"
        }
      }
    ]
  },
  "suggest" : {
    "my-suggestion" : [
      {
        "text" : "bleed",
        "offset" : 0,
        "length" : 5,
        "options" : [
          {
            "text" : "blend",
            "score" : 0.8,
            "freq" : 1
          },
          {
            "text" : "blood",
            "score" : 0.6,
            "freq" : 1
          }
        ]
      }
    ]
  }
}

上面的结果显示:我们找到一个 name 字段为 bold 的文档,同时我们也找到了 bleed 这个术语的被建议的术语:blendblood。请注意 bleed 并不存在于我们的索引之中。从上面的结果中,我们也可以看到在 options 中返回的结果中有 score。这个分数越高,表明匹配度越高。

假如我们用正确的已经存在于索引之中的词来使用 term suggest:

GET term-suggest/_search
{
  "suggest": {
    "my-suggestion": {
      "text": "blood",
      "term": {
        "field": "name"
      }
    }
  }
}

那么显示的结果是:

  "suggest" : {
    "my-suggestion" : [
      {
        "text" : "blood",
        "offset" : 0,
        "length" : 5,
        "options" : [ ]
      }
    ]
  }

我们可以看出来没有任何的建议的术语。

用例2 - Multi-term suggester

另一个有用的功能是 multi-term 建议请求。 在这里,我们可以在同一个建议查询中打包几个术语建议请求。 在下面的示例中查看其工作方式:

GET term-suggest/_search
{
  "suggest": {
    "my-suggest": {
      "text": "bleed",
      "term": {
        "field": "name"
      }
    },
    "my-suggest2": {
      "text": "blod",
      "term": {
        "field": "name"
      }
    }
  }
}

在上面的示例中,我们仅对一个字段(“name”)使用了拼写检查。 我们也可以通过简单地用另一个替换 “field” 值来对多个字段做同样的事情。显示结果:

  "suggest" : {
    "my-suggest" : [
      {
        "text" : "bleed",
        "offset" : 0,
        "length" : 5,
        "options" : [
          {
            "text" : "blend",
            "score" : 0.8,
            "freq" : 1
          },
          {
            "text" : "blood",
            "score" : 0.6,
            "freq" : 1
          }
        ]
      }
    ],
    "my-suggest2" : [
      {
        "text" : "blod",
        "offset" : 0,
        "length" : 4,
        "options" : [
          {
            "text" : "blood",
            "score" : 0.75,
            "freq" : 1
          },
          {
            "text" : "bold",
            "score" : 0.75,
            "freq" : 1
          },
          {
            "text" : "bald",
            "score" : 0.5,
            "freq" : 1
          },
          {
            "text" : "blend",
            "score" : 0.5,
            "freq" : 1
          }
        ]
      }
    ]
  }

在返回的结果中我们可以看到有两个不同的数组 my-suggest 及 my-suggest2。

用例3 - 全局建议文字

为了避免重复建议文本,我们可以定义一个全局文本。 在下面的示例中,建议文本是全局定义的,它适用于我们指定的两个建议查询。 当你针对索引中的两个不同字段发送建议查询时,此功能很有用。 假设索引中还有另一个字段 “substance”,我们可以使用全局文本创建以下建议查询。

GET term-suggest/_search
{
  "suggest": {
    "text": "blod",
    "my-suggest": {
      "term": {
        "field": "name"
      }
    },
    "my-suggest2": {
      "term": {
        "field": "substance"
      }
    }
  }
}

在以上请求中,我们可以看到为建议查询定义了全局建议文本 “blod”,并且两个子查询针对索引中的两个字段使用此文本。 这样,我们可以一次定义一个全局文本,然后将其自动重用于许多字段。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值