【问题标题】:elasticsearch query string dont search by word partelasticsearch查询字符串不按单词部分搜索
【发布时间】:2015-12-17 09:42:17
【问题描述】:

我正在发送此请求

curl -XGET 'host/process_test_3/14/_search' -d '{
  "query" : {
    "query_string" : {
      "query" : "\"*cor interface*\"",
      "fields" : ["title", "obj_id"]
    }
  }
}'

我得到了正确的结果

{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 5.421598,
    "hits": [
      {
        "_index": "process_test_3",
        "_type": "14",
        "_id": "141_dashboard_14",
        "_score": 5.421598,
        "_source": {
          "obj_type": "dashboard",
          "obj_id": "141",
          "title": "Cor Interface Monitoring"
        }
      }
    ]
  }
}

但是当我想按单词部分搜索时,例如

curl -XGET 'host/process_test_3/14/_search' -d '
{
  "query" : {
    "query_string" : {
      "query" : "\"*cor inter*\"",
      "fields" : ["title", "obj_id"]
    }
  }
}'

我没有得到任何结果:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : []
  }
}

我做错了什么?

【问题讨论】:

  • 你知道你是只搜索前缀(即单词的开头)还是你的单词的任何子字符串?
  • 任何子字符串,但如果这种情况的解决方案不同,最好同时查看

标签: elasticsearch query-string


【解决方案1】:

这是因为您的title 字段可能已被标准分析器(默认设置)分析,并且标题Cor Interface Monitoring 已被标记为corinterfacemonitoring 三个标记。

为了搜索单词的任何子字符串,您需要创建一个利用 ngram token filtercustom analyzer,以便同时索引每个标记的所有子字符串。

您可以这样创建索引:

curl -XPUT localhost:9200/process_test_3 -d '{
  "settings": {
    "analysis": {
      "analyzer": {
        "substring_analyzer": {
          "tokenizer": "standard",
          "filter": ["lowercase", "substring"]
        }
      },
      "filter": {
        "substring": {
          "type": "nGram",
          "min_gram": 2,
          "max_gram": 15
        }
      }
    }
  },
  "mappings": {
    "14": {
      "properties": {
        "title": {
          "type": "string",
          "analyzer": "substring_analyzer"
        }
      }
    }
  }
}'

然后您可以重新索引您的数据。这将做的是标题Cor Interface Monitoring 现在将被标记为:

  • co, cor, or
  • inintinteinterinterf
  • momonmoni

这样您的第二个搜索查询现在将返回您期望的文档,因为标记 corinter 现在将匹配。

【讨论】:

  • 你是对的,我使用了自定义分析器。您的设置一切正常,非常感谢!
  • 太棒了,很高兴它有帮助!
【解决方案2】:

+1 对 Val 的解决方案。 只是想添加一些东西。 由于您的查询相对简单,您可能需要查看match/match_phrase 查询。匹配查询确实具有像 query_string 这样的正则表达式解析,因此更轻。 您可以在这里找到详细信息:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html

【讨论】:

  • 匹配查询不会将“*”字符解释为通配符,这就是为什么 - query_string
  • 我的解决方案只是 Val 解决方案的延续。您首先需要 Val 所描述的 substring_analyzer。之后,您可以执行匹配查询。您不需要 * 在开头和/或结尾。匹配查询不将“*”解释为通配符是使它更快的原因。此外,还有 multi_match 查询,它采用您原始问题中的字段列表。因此,结合正确的映射、match/multi_match 查询和运算符值,您可以获得所需的行为。将 query_string 用于需要正则表达式解析的复杂查询。
  • 感谢扩展回答,现在我了解它的主要关键并会尝试。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
相关资源
最近更新 更多