在具有特殊字符的自定义关键字字段上使用术语查询时出现意外结果
Unexpected results when using terms query on custom keyword field with special characters
我有一个包含以下字段的索引:
myField: {
type: "text",
fields: {
keyword: {
type: "keyword",
ignore_above: 256
},
keyword_lowercase: {
type: "text",
analyzer: "lowercase_keyword_analyzer",
fielddata: true
}
},
analyzer: "autocomplete_analyzer",
search_analyzer: "autocomplete_search_analyzer"
},
分析器:
lowercase_keyword_analyzer: {
filter: [
"lowercase",
"asciifolding"
],
type: "custom",
tokenizer: "keyword"
},
autocomplete_search_analyzer: {
filter: [
"lowercase",
"asciifolding"
],
type: "custom",
tokenizer: "standard"
},
autocomplete_analyzer: {
filter: [
"lowercase",
"asciifolding",
"autocomplete_edge_ngram"
],
type: "custom",
tokenizer: "standard"
}
我有一份文件,其值为:欧舒丹
MATCH 查询:
"query": {
"bool": {
"should": [
{
"match": {
"myField.keyword_lowercase": {
"query": "l’occitane"
}
}
}]
}
}
找到它,但是一个 TERM 查询:
"query": {
"bool": {
"should": [
{
"term": {
"myField.keyword_lowercase": {
"value": "l’occitane"
}
}
}]
}
}
不会。奇怪的是,如果我将文档中的撇号从 ' 更改为 ':
"query": {
"bool": {
"should": [
{
"term": {
"myField.keyword_lowercase": {
"value": "l'occitane"
}
}
}]
}
}
搜索词现在可以使用了。我发现这个问题与其他带有特殊字符的词有关,据我所知,asciifolding 过滤器应该可以防止这种情况发生。
这是怎么回事?
有点难看,但正如您所说,这是两种撇号。我会说一个是 single quote
,法语是 apostrophe
。
分别为它们建立索引
POST mag/_doc
{"myField": "l'occitane"}
POST mag/_doc
{"myField":"l’occitane"}
然后通过 analyzed 关键字聚合:
GET mag/_search
{
"aggs": {
"by_terms": {
"terms": {
"field": "myField.keyword_lowercase"
}
}
}
}
屈服
"buckets" : [
{
"key" : "l'occitane",
"doc_count" : 2
}
]
这意味着 asciifolding fiter 将 apostrophe
转换为 single-quote
并且由于术语查询对倒排索引中的精确值进行操作,因此您将无法使用 apostrophe
。你需要去
...
{
"term": {
"myField.keyword_lowercase": {
"value": "l'occitane"
}
}
}
...
如果您确实想要应用小写字词查询,则需要删除 asciifolding 或在 myField
中添加另一个映射字段,而不使用上述 asciifolding。这样,查询 myField.keyword_lowercase_no_ascii
将 使用撇号。
我有一个包含以下字段的索引:
myField: {
type: "text",
fields: {
keyword: {
type: "keyword",
ignore_above: 256
},
keyword_lowercase: {
type: "text",
analyzer: "lowercase_keyword_analyzer",
fielddata: true
}
},
analyzer: "autocomplete_analyzer",
search_analyzer: "autocomplete_search_analyzer"
},
分析器:
lowercase_keyword_analyzer: {
filter: [
"lowercase",
"asciifolding"
],
type: "custom",
tokenizer: "keyword"
},
autocomplete_search_analyzer: {
filter: [
"lowercase",
"asciifolding"
],
type: "custom",
tokenizer: "standard"
},
autocomplete_analyzer: {
filter: [
"lowercase",
"asciifolding",
"autocomplete_edge_ngram"
],
type: "custom",
tokenizer: "standard"
}
我有一份文件,其值为:欧舒丹
MATCH 查询:
"query": {
"bool": {
"should": [
{
"match": {
"myField.keyword_lowercase": {
"query": "l’occitane"
}
}
}]
}
}
找到它,但是一个 TERM 查询:
"query": {
"bool": {
"should": [
{
"term": {
"myField.keyword_lowercase": {
"value": "l’occitane"
}
}
}]
}
}
不会。奇怪的是,如果我将文档中的撇号从 ' 更改为 ':
"query": {
"bool": {
"should": [
{
"term": {
"myField.keyword_lowercase": {
"value": "l'occitane"
}
}
}]
}
}
搜索词现在可以使用了。我发现这个问题与其他带有特殊字符的词有关,据我所知,asciifolding 过滤器应该可以防止这种情况发生。
这是怎么回事?
有点难看,但正如您所说,这是两种撇号。我会说一个是 single quote
,法语是 apostrophe
。
分别为它们建立索引
POST mag/_doc
{"myField": "l'occitane"}
POST mag/_doc
{"myField":"l’occitane"}
然后通过 analyzed 关键字聚合:
GET mag/_search
{
"aggs": {
"by_terms": {
"terms": {
"field": "myField.keyword_lowercase"
}
}
}
}
屈服
"buckets" : [
{
"key" : "l'occitane",
"doc_count" : 2
}
]
这意味着 asciifolding fiter 将 apostrophe
转换为 single-quote
并且由于术语查询对倒排索引中的精确值进行操作,因此您将无法使用 apostrophe
。你需要去
...
{
"term": {
"myField.keyword_lowercase": {
"value": "l'occitane"
}
}
}
...
如果您确实想要应用小写字词查询,则需要删除 asciifolding 或在 myField
中添加另一个映射字段,而不使用上述 asciifolding。这样,查询 myField.keyword_lowercase_no_ascii
将 使用撇号。