【问题标题】:Elastic Search wildcard search with spaces带空格的 Elastic Search 通配符搜索
【发布时间】:2015-07-18 18:35:48
【问题描述】:

我有以下问题。我正在尝试查找“hello world”的值,但它返回零结果。但是,当value = 'hello*' 时,它确实给了我预期的结果。知道如何更改我的查询以给我 hello world 结果吗?我试过*hello world*,但由于某种原因,它不会搜索任何带有空格的东西。

我认为这与空格有关,因为当我尝试搜索 "* *" 时,它没有给我任何结果。但我知道我有很多带有空格的值。任何想法都会有所帮助!

 {
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {
            "terms": {
              "variant": [
                "collection"
              ]
            }
          }
        ]
      },
      "query": {
        "wildcard": {
          "name": {
            "value": "hello world"
          }
        }
      }
    }
  }
}

【问题讨论】:

    标签: elasticsearch wildcard spaces


    【解决方案1】:

    您为字段name 使用的映射是什么?如果您没有定义任何映射或者您刚刚将类型定义为字符串(没有任何分析器),那么将使用标准分析器分析该字段。这将分别创建标记为“hello”和“world”。这意味着通配符查询将适用于 *ell**wor* 之类的内容,但不适用于空格。

    您必须更改映射以将字段“名称”设置为 not_analyzed,然后使用空格进行通配符搜索。

    请注意: 通配符搜索量很大。如果您想进行部分匹配搜索(相当于 %like%),您可以在分析器中使用 ngram 标记过滤器并进行术语搜索。它将负责匹配部分字符串并具有更好的性能。

    【讨论】:

      【解决方案2】:

      The "string" type is legacy and with index "not_analyzed" it is mapped to the type "keyword" which is not divided into substrings. 我之前遇到了包括空格在内的查询问题,并通过在空格处将查询拆分为子字符串并进行组合查询来解决它,为每个子字符串添加一个通配符对象,使用“bool”和“must” ":

      {
        "query": {
          "bool": {
            "must": [
              {
                "wildcard": {
                  "name": "*hello*"
                }
              },
              {
                "wildcard": {
                  "name": "*world*"
                }
              }
            ]
          }
        }
      }
      

      这种方法有个小缺点,就是“地狱世界!”和其他意外的字符串最终会出现在您的结果中。您可以通过将除最后一个子字符串之外的所有字符串的“通配符”更改为“匹配”来解决此问题。

      您应该尝试通过首先更改字段的类型来解决它:

      PUT your_index
      {
        "mappings": {
          "your_index": {
            "properties": {
              "your_field1": {
                 "type": "keyword"
                  },
              "your_field2": {
                  "type": "string",
                  "index": "not_analyzed"
                  }
               }
            }
          }
        }
      }
      

      【讨论】:

        【解决方案3】:

        你需要使用

        match_phrase: {"field_name": "some phrase with spaces"}
        

        正如官方文档中提到的,

        要执行短语搜索而不是匹配单个字词,请使用 match_phrase 而不是 match

        【讨论】:

        • 这个答案得 0 分,是我找到的唯一有效答案。当您不允许更改映射时,它也可以解决问题。
        • 正确答案。
        • 这也适用于我的情况,谢谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        相关资源
        最近更新 更多