使用Elasticsearch忽略前导零

时间:2015-06-04 17:27:06

标签: elasticsearch full-text-search

我正在尝试创建一个搜索栏,其中最常见的查询将用于" serviceOrderNo"。 " serviceOrderNo"不是数据库中的 number 字段,它是字符串字段。例子:

000000007
000000002
WO0000042
123456789
AllTextss
000000054
000000065
000000874

最常见的格式只是一个由一定数量的零进行的整数。

如何设置Elasticsearch以便搜索" 65"将匹配" 000000065"?我还希望优先考虑" serviceOrderNo"领域(我已经工作了)。这就是我现在所处的位置:

{
   "query": {
      "multi_match": {
         "query": "65",
         "fields": ["serviceOrderNo^2", "_all"],
      }
   }
}

2 个答案:

答案 0 :(得分:7)

这样做的一种方法是使用lucene flavor常规exression查询:

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html

"query": {
     "regexp":{
        "serviceOrderNo": "[0]*65"
     }
}

此外,查询字符串查询还支持一小组特殊字符,更有限的正则表达式字符集,AS WELL AS lucene正则表达式查询将如下所示: https://www.elastic.co/guide/en/elasticsearch/reference/1.x/query-dsl-query-string-query.html

"query": {
    "query_string": {
       "default_field": "serviceOrderNo",
       "query": "0*65"
    }
}

这些是相当简单的正则表达式,两者都表示与括号[0]中包含的字符匹配或字符0无限次*

如果您能够重新编制索引,或者尚未将数据编入索引,那么您还可以通过编写自定义分析器使自己更轻松。现在,您在serviceOrderNo字段上使用字符串的默认分析器。索引"serviceOrderNo":"00000065"时,ES将其解释为00000065。

您的自定义分析器可以使用相同的正则表达式将此字段标记为“0000065”和“65”。这样做的好处是Regex只在索引时运行一次,而不是每次运行查询,因为ES将搜索“0000065”和“65”。

您还可以查看the ES website documentation on Analyzers

"settings":{
    "analysis": {
        "filter":{
           "trimZero": {
                "type":"pattern_capture",
                "patterns":"^0*([0-9]*$)"
           }
        },
       "analyzer": {
           "serviceOrderNo":{
               "type":"custom",
               "tokenizer":"standard",
               "filter":"trimZero"
           }
        }
    }
},
"mappings":{
    "serviceorderdto": {
        "properties":{
            "serviceOrderNo":{
                "type":"String",
                "analyzer":"serviceOrderNo"
            }
        }
    }
}

答案 1 :(得分:0)

这样做的一种方法是使用ngram token filter以便" 12345"被标记为:

[ 1, 2, 3, 4, 5 ]
[ 12, 23, 34, 45 ]
[ 123, 234, 345 ]
[ 12345 ]

当以这种方式标记时," 65"是" 000000065"。

的匹配

要进行此设置,请创建一个新索引,该索引具有使用ngram过滤器的自定义分析器:

POST /my-index
{
   "mappings": {
      "serviceorderdto": {
         "properties": {
            "serviceOrderNo": {
               "type": "string",
               "analyzer": "autocomplete"
            }
         }
      }
   },
   "settings": {
      "analysis": {
         "filter": {
            "autocomplete_filter": {
               "type": "ngram",
               "min_gram": 1,
               "max_gram": 20
            }
         },
         "analyzer": {
            "autocomplete": {
               "type": "custom",
               "tokenizer": "standard",
               "filter": [
                  "lowercase",
                  "autocomplete_filter"
               ]
            }
         }
      }
   }
}

索引一些数据。 然后运行您的查询:

GET /my-index/_search
{
    "query": {
        "multi_match": {
            "query": "55", 
            "fields": [
               "serviceOrderNo^2",
               "_all"
            ]
        }
    }
}