ElasticSearch 5 不会找到关键字包含 space 的文档
ElasticSearch 5 won't find documents with keyword including space
I/m 索引文件格式如下:
{
"title": "this is the title",
"brand": "brand here",
"filters": ["filter1", "filter2", "Sin filters", "Camera IP"]
"active": true
}
然后查询如下所示:
'query': {
'function_score': {
'query': {
'bool': {
'filter': [
{
'term': {
'active': True
}
}
],
'must': [
{
'terms': {
'filters': ['camera ip']
}
}
]
}
}
}
}
我无法 return 任何带有 "Camera IP" 过滤器(或此字符串的任何变体,小写等)的文档,但是 Es return 带有过滤器的文档: "Sin filters".
索引是使用以下设置创建的。请注意,"filter" 字段将属于默认模板,类型为关键字
"settings":{
"index":{
"analysis":{
"analyzer":{
"keylower":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_as_keywords": {
"mapping": {
"index": "not_analyzed",
"type" : "keyword",
**"analyzer": "keylower"** # I also tried with and without changing this analyzer
},
"match": "*",
"match_mapping_type": "string"
}
},
{
"integers": {
"mapping": {
"type": "integer"
},
"match": "*",
"match_mapping_type": "long"
}
},
{
"floats": {
"mapping": {
"type": "float"
},
"match": "*",
"match_mapping_type": "double"
}
}
]
}
}
我错过了什么?奇怪的是 return 那些有 "Sin filters" 过滤器但没有 "Camera IP".
谢谢。
您的过滤器 'filters': ['camera ip']
查找 camera ip
,而在映射中您将字段 filters
作为类型 keyword
,elasticsearch 查找完全匹配。因此,为了找到该字段,您需要有一个精确的字符串,您可以为匹配项建立索引。如果您的用例不需要完全匹配,请将类型更改为 text
,elasticsearch 在索引之前对其进行分析。有关文本数据类型的更多信息 here and keyword datatype here
您似乎希望过滤器为小写且不被标记化。我认为您的查询的问题在于您将字符串类型设置为 "keyword" 并且 ES 不会分析这些字段,甚至不会更改它们的大小写:
Keyword fields are only searchable by their exact value.
这就是为什么在您的设置下您仍然可以使用如下查询检索文档的原因:{"query": {"term": {"filters": "Camera IP"}}}'
。
由于您希望分析器在索引之前更改文本的大小写,因此您应该通过将映射更改为如下内容来将类型设置为 text
:
{"settings":{
"index": {
"analysis":{
"analyzer":{
"test_analyzer":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_as_keywords": {
"mapping": {
"type": "text",
"index": "not_analyzed",
"analyzer": "test_analyzer"
},
"match": "*",
"match_mapping_type": "string"
}
}
]
}
}}
I/m 索引文件格式如下:
{
"title": "this is the title",
"brand": "brand here",
"filters": ["filter1", "filter2", "Sin filters", "Camera IP"]
"active": true
}
然后查询如下所示:
'query': {
'function_score': {
'query': {
'bool': {
'filter': [
{
'term': {
'active': True
}
}
],
'must': [
{
'terms': {
'filters': ['camera ip']
}
}
]
}
}
}
}
我无法 return 任何带有 "Camera IP" 过滤器(或此字符串的任何变体,小写等)的文档,但是 Es return 带有过滤器的文档: "Sin filters".
索引是使用以下设置创建的。请注意,"filter" 字段将属于默认模板,类型为关键字
"settings":{
"index":{
"analysis":{
"analyzer":{
"keylower":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_as_keywords": {
"mapping": {
"index": "not_analyzed",
"type" : "keyword",
**"analyzer": "keylower"** # I also tried with and without changing this analyzer
},
"match": "*",
"match_mapping_type": "string"
}
},
{
"integers": {
"mapping": {
"type": "integer"
},
"match": "*",
"match_mapping_type": "long"
}
},
{
"floats": {
"mapping": {
"type": "float"
},
"match": "*",
"match_mapping_type": "double"
}
}
]
}
}
我错过了什么?奇怪的是 return 那些有 "Sin filters" 过滤器但没有 "Camera IP".
谢谢。
您的过滤器 'filters': ['camera ip']
查找 camera ip
,而在映射中您将字段 filters
作为类型 keyword
,elasticsearch 查找完全匹配。因此,为了找到该字段,您需要有一个精确的字符串,您可以为匹配项建立索引。如果您的用例不需要完全匹配,请将类型更改为 text
,elasticsearch 在索引之前对其进行分析。有关文本数据类型的更多信息 here and keyword datatype here
您似乎希望过滤器为小写且不被标记化。我认为您的查询的问题在于您将字符串类型设置为 "keyword" 并且 ES 不会分析这些字段,甚至不会更改它们的大小写:
Keyword fields are only searchable by their exact value.
这就是为什么在您的设置下您仍然可以使用如下查询检索文档的原因:{"query": {"term": {"filters": "Camera IP"}}}'
。
由于您希望分析器在索引之前更改文本的大小写,因此您应该通过将映射更改为如下内容来将类型设置为 text
:
{"settings":{
"index": {
"analysis":{
"analyzer":{
"test_analyzer":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_as_keywords": {
"mapping": {
"type": "text",
"index": "not_analyzed",
"analyzer": "test_analyzer"
},
"match": "*",
"match_mapping_type": "string"
}
}
]
}
}}