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

Elastic 专栏收录该内容
494 篇文章 87 订阅

在这篇文章中,我们来讲述 Elasticsearch 中的 suggester。通过使用 suggester,根据提供的文本建议外观相似的字词。 建议功能的某些部分仍在开发中。suggester的 官方文档在地址 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html

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 这个术语的被建议的术语:blend 及 blood。请注意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”,并且两个子查询针对索引中的两个字段使用此文本。 这样,我们可以一次定义一个全局文本,然后将其自动重用于许多字段。

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值