首页 > 解决方案 > 如何在 ElasticSearch 中实现此类查询?

问题描述

我已将这样的文档添加到我的索引中

POST /analyzer3/books
{
  "title": "The other day I went with my mom to the pool and had a lot of fun"
}

然后我做这样的查询

GET /analyzer3/_analyze
{
  "analyzer": "english",
  "text": "\"The * day I went with my * to the\""
}

并且成功返回了之前添加的文档。

我的想法是使用引号使查询变得准确,但也可以使用可以替换任何单词的通配符。谷歌有这个确切的功能,例如,您可以在其中搜索这样的查询,"I'm * the university"它会返回包含诸如I'm studying in the university right now等文本的页面结果。

但是我想知道是否有另一种方法可以做到这一点。

我主要担心的是,这似乎不适用于日语和中文等其他语言。我尝试了许多分析器和标记器都无济于事。

任何答案表示赞赏。

标签: elasticsearchlucenefull-text-search

解决方案


Elasticsearch 没有开箱即用的类似 Google 的搜索,但您可以构建类似的东西。

让我们假设当有人引用搜索文本时,他们想要的是匹配短语查询。基本上删除\"并搜索剩余的字符串作为短语。

PUT test/_doc/1
{
  "title": "The other day I went with my mom to the pool and had a lot of fun"
}

GET test/_search
{
  "query": {
    "match_phrase": {
      "title": "The other day I went with my mom to the pool and had a lot of fun"
    }
  }
}

因为*它变得更有趣了。您可以从中进行多个短语搜索并将它们组合起来。例子:

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "title": "The"
          }
        },
        {
          "match_phrase": {
            "title": "day I went with my"
          }
        },
        {
          "match_phrase": {
            "title": "to the"
          }
        }
      ]
    }
  }
}

或者您可以在短语搜索中使用 slop。搜索查询中的所有术语都必须存在(除非它们被标记器删除或作为停用词),但匹配的短语可以在短语中包含其他单词。在这里,我们可以将每个 * 替换为 1 个其他单词,因此总共 2 个 slop。如果您想要超过 1 个单词来代替每个 *,您将需要选择一个更高的斜率:

GET test/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "The * day I went with my * to the",
        "slop": 2
      }
    }
  }
}

另一种选择可能是shingles,但这是一个更高级的概念,我现在将从基础开始。


推荐阅读