not_analyzed 字段上的 elasticsearch 不区分大小写的术语过滤器搜索
elasticsearch case insensitive term filter search on not_analyzed field
这里有类似的问题Elasticsearch Map case insensitive to not_analyzed documents,但我的问题略有不同,因为我处理的是特殊字符。
大多数人建议结合使用 keyword analyzer
和 lowercase filter
。但是,这对我的情况不起作用,因为关键字分析器对空格和 ^, #, etc
等特殊字符进行标记。这打破了我想要的支持类型。
即
^HELLOWORLD
应该通过搜索^helloworld
来匹配,而不是helloworld
#FooBar
应该匹配 #foobar
而不是 foobar
.
Foo Bar
应与 foo bar
匹配,而不是 foo
或 bar
.
与我们在此处看到的功能类似 https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_term_filter_with_numbers,但不区分大小写。
有谁知道如何做到这一点?
编辑 1:
看来我的问题的核心是multi-field,因为关键字+小写似乎解决了标题中提出的问题。但是,针对 multi-field 值 属性.
提出这个问题会更准确
test_mapping.json:
{
"properties" : {
"productID1" : {
"type" : "string",
"index_analyzer" : "keyword_lowercase",
"search_analyzer" : "keyword_lowercase"
},
"productID2" : {
"type": "multi_field",
"keyword_edge_ID": {
"type": "string",
"index_analyzer":"keyword_lowercase_edge",
"search_analyzer":"keyword_lowercase_edge"
},
"productID2": {
"type": "string",
"index": "analyzed",
"store": "yes",
"index_analyzer":"keyword_lowercase",
"search_analyzer":"keyword_lowercase"
}
}
}
}
test.json:
{
"index": {
"analysis": {
"filter":{
"edgengramfilter": {
"type": "edgeNgram",
"side": "front",
"min_gram": 1,
"max_gram": 32
}
},
"analyzer": {
"keyword_lowercase" : {
"type" : "custom",
"tokenizer": "keyword",
"filter": "lowercase"
},
"keyword_lowercase_edge": {
"tokenizer": "keyword",
"filter": ["lowercase", "edgengramfilter"]
}
}
}
}
}
Shell 使用映射创建索引的脚本:
#!/bin/sh
ES_URL="http://localhost:9200"
curl -XDELETE $ES_URL/test
curl -XPOST $ES_URL/test/ --data-binary @test.json
curl -XPOST $ES_URL/test/query/_mapping --data-binary @test_mapping.json
POST localhost:9200/test/query
:
{
"productID1" : "^A",
"productID2" : "^A"
}
我想要它,以便我可以用“^A”匹配 productID2,但它现在没有返回任何结果,但是当我对 productID1 执行相同的查询时它有效。 {"query": { "match": { "productID2": "^A" }}}
正如您在下面的示例中看到的那样,keyword
tokenizer 和 lowercase
过滤器正是这样做的 - 它在保留的同时将整个值小写所有空格和特殊字符。如何使用它的例子可以在 this answer.
中找到
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "^HELLOWORLD"
{
"tokens" : [ {
"token" : "^helloworld",
"start_offset" : 0,
"end_offset" : 11,
"type" : "word",
"position" : 1
} ]
}
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "#FooBar"
{
"tokens" : [ {
"token" : "#foobar",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 1
} ]
}
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "Foo Bar"
{
"tokens" : [ {
"token" : "foo bar",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 1
} ]
}
这里有类似的问题Elasticsearch Map case insensitive to not_analyzed documents,但我的问题略有不同,因为我处理的是特殊字符。
大多数人建议结合使用 keyword analyzer
和 lowercase filter
。但是,这对我的情况不起作用,因为关键字分析器对空格和 ^, #, etc
等特殊字符进行标记。这打破了我想要的支持类型。
即
^HELLOWORLD
应该通过搜索^helloworld
来匹配,而不是helloworld
#FooBar
应该匹配#foobar
而不是foobar
.Foo Bar
应与foo bar
匹配,而不是foo
或bar
.
与我们在此处看到的功能类似 https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_term_filter_with_numbers,但不区分大小写。
有谁知道如何做到这一点?
编辑 1:
看来我的问题的核心是multi-field,因为关键字+小写似乎解决了标题中提出的问题。但是,针对 multi-field 值 属性.
提出这个问题会更准确test_mapping.json:
{
"properties" : {
"productID1" : {
"type" : "string",
"index_analyzer" : "keyword_lowercase",
"search_analyzer" : "keyword_lowercase"
},
"productID2" : {
"type": "multi_field",
"keyword_edge_ID": {
"type": "string",
"index_analyzer":"keyword_lowercase_edge",
"search_analyzer":"keyword_lowercase_edge"
},
"productID2": {
"type": "string",
"index": "analyzed",
"store": "yes",
"index_analyzer":"keyword_lowercase",
"search_analyzer":"keyword_lowercase"
}
}
}
}
test.json:
{
"index": {
"analysis": {
"filter":{
"edgengramfilter": {
"type": "edgeNgram",
"side": "front",
"min_gram": 1,
"max_gram": 32
}
},
"analyzer": {
"keyword_lowercase" : {
"type" : "custom",
"tokenizer": "keyword",
"filter": "lowercase"
},
"keyword_lowercase_edge": {
"tokenizer": "keyword",
"filter": ["lowercase", "edgengramfilter"]
}
}
}
}
}
Shell 使用映射创建索引的脚本:
#!/bin/sh
ES_URL="http://localhost:9200"
curl -XDELETE $ES_URL/test
curl -XPOST $ES_URL/test/ --data-binary @test.json
curl -XPOST $ES_URL/test/query/_mapping --data-binary @test_mapping.json
POST localhost:9200/test/query
:
{
"productID1" : "^A",
"productID2" : "^A"
}
我想要它,以便我可以用“^A”匹配 productID2,但它现在没有返回任何结果,但是当我对 productID1 执行相同的查询时它有效。 {"query": { "match": { "productID2": "^A" }}}
正如您在下面的示例中看到的那样,keyword
tokenizer 和 lowercase
过滤器正是这样做的 - 它在保留的同时将整个值小写所有空格和特殊字符。如何使用它的例子可以在 this answer.
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "^HELLOWORLD"
{
"tokens" : [ {
"token" : "^helloworld",
"start_offset" : 0,
"end_offset" : 11,
"type" : "word",
"position" : 1
} ]
}
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "#FooBar"
{
"tokens" : [ {
"token" : "#foobar",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 1
} ]
}
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "Foo Bar"
{
"tokens" : [ {
"token" : "foo bar",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 1
} ]
}