【问题标题】:Elasticsearch search fails in field with special character and wildcardElasticsearch 搜索在具有特殊字符和通配符的字段中失败
【发布时间】:2014-12-04 13:38:54
【问题描述】:

我在 Elasticsearch 中有一个值为“PEI.H.02354.01.”的字段。当我用querystring 搜索时

{  
   "query":{  
      "query_string":{  
         "query":"field:PEI.H.02354.01.",
         "default_operator":"AND"
      }
   }
}

然后返回一个结果,这是正确的行为。但如果我使用通配符搜索,则不会返回任何结果,例如

{  
   "query":{  
      "query_string":{  
         "query":"field:PEI.H.02354.01.*",
         "default_operator":"AND"
      }
   }
}

该字段是字符串类型并已分析。下面是创建索引的代码,包括分析器和映射。

{
   "settings":{  
      "analysis":{  
         "analyzer":{  
            "number":{  
               "type":"custom",
               "tokenizer":"keyword",
               "filter":[  
                  "lowercase"
               ],
               "char_filter":[  
                  "number_filter"
               ]
            },
            "diacritical":{  
               "type":"custom",
               "tokenizer":"standard",
               "filter":[  
                  "standard",
                  "lowercase",
                  "asciifolding",
                  "nfd_normalizer"
               ]
            }
         },
         "filter":{  
            "nfd_normalizer":{  
               "type":"icu_normalizer",
               "name":"nfc"
            }
         },
         "char_filter":{  
            "number_filter":{  
               "type":"pattern_replace",
               "pattern":"[^\\d]+",
               "replacement":""
            }
         }
      }
   },
   "mappings":{  
      "testType":{  
         "_source":{  
            "enabled":false
         },
         "_all":{  
            "enabled":false
         },
         "_timestamp":{  
            "enabled":"true",
            "store":"yes"
         },
         "properties":{  
            "field":{  
               "store":"yes",
               "type":"string",
               "index":"analyzed",
               "analyzer":"diacritical"
            }
         }
     }    
}

最后是一个示例插入

{
    field: "PEI.H.02354.01."
}

有谁知道为什么会发生这种情况以及如何解决这个问题?

【问题讨论】:

    标签: elasticsearch wildcard


    【解决方案1】:

    请参阅query_string 文档:

    默认情况下不分析通配符 — 它们是小写的(lowercase_expanded_terms 默认为 true),但不进行进一步分析

    您存储的数据分为两个部分:

    curl -XGET 'localhost:9200/myindex/_analyze?analyzer=diacritical&pretty' -d 'PEI.H.02354.01'
    {
      "tokens" : [ {
        "token" : "pei.h",
        "start_offset" : 0,
        "end_offset" : 5,
        "type" : "<ALPHANUM>",
        "position" : 1
      }, {
        "token" : "02354.01",
        "start_offset" : 6,
        "end_offset" : 14,
        "type" : "<NUM>",
        "position" : 2
      } ]
    }
    

    但由于您的带有通配符的搜索词只变成了pei.h.02354.01.*,所以它不会匹配。

    但是,如果将 analyze_wildcard 设置为 true,您确实会获得成功:

    curl -XGET "http://localhost:9200/myindex/testType/_search?pretty" -d'
    > {
    >    "query":{
    >       "query_string":{
    >          "query":"field:PEI.H.02354.01.*",
    >          "default_operator":"AND",
    >          "analyze_wildcard": true
    >       }
    >    }
    > }'
    {
      "took" : 5,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "failed" : 0
      },
      "hits" : {
        "total" : 2,
        "max_score" : 1.4142135,
    

    【讨论】:

    • 使用它确实会返回结果,但并非所有结果都是正确的,例如我也得到了 PEI.H.4545.01。正如您所说,如果分析了搜索词并且基本上ES搜索的是pei.h OR 02354.01,那么这是有道理的。但是有没有办法避免这种情况并搜索 PEI.H.02354.01。总的来说,而不是把它分成两个方面?
    • 听起来您想将 PEI.H.02354.01 视为单个字符串 - 如果是这样,您需要更改分析器,例如仅对空格进行标记。
    • 可能对于这种搜索,您应该使用带有不同分析器的多字段。
    • 我用空白分词器替换了标准分词器,这样行为是正确的,即标点符号没有被分词。
    猜你喜欢
    • 1970-01-01
    • 2021-10-11
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多