使用Elasticsearch忽略前导零

Jos*_*ham 4 full-text-search elasticsearch

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

000000007
000000002
WO0000042
123456789
AllTextss
000000054
000000065
000000874
Run Code Online (Sandbox Code Playgroud)

最常见的格式是一个整数,由一些零开始.

如何设置Elasticsearch以便搜索"65"将匹配"000000065"?我还想优先考虑"serviceOrderNo"字段(我已经有了).这就是我现在所处的位置:

{
   "query": {
      "multi_match": {
         "query": "65",
         "fields": ["serviceOrderNo^2", "_all"],
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*bes 7

一种方法是使用lucene flavor常规exression查询:

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

"query": {
     "regexp":{
        "serviceOrderNo": "[0]*65"
     }
}
Run Code Online (Sandbox Code Playgroud)

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

"query": {
    "query_string": {
       "default_field": "serviceOrderNo",
       "query": "0*65"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

您还可以查看有关分析仪的ES网站文档.

"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"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)