我正在尝试创建一个搜索栏,其中最常见的查询将用于" serviceOrderNo"。 " serviceOrderNo"不是数据库中的 number 字段,它是字符串字段。例子:
000000007
000000002
WO0000042
123456789
AllTextss
000000054
000000065
000000874
最常见的格式只是一个由一定数量的零进行的整数。
如何设置Elasticsearch以便搜索" 65"将匹配" 000000065"?我还希望优先考虑" serviceOrderNo"领域(我已经工作了)。这就是我现在所处的位置:
{
"query": {
"multi_match": {
"query": "65",
"fields": ["serviceOrderNo^2", "_all"],
}
}
}
答案 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"
]
}
}
}