Elasticsearch 上的短语和通配符查询
Phrase & wildcard queries on Elasticsearch
我在尝试创建只能匹配整个短语但也允许使用通配符的查询时遇到了一些困难。
基本上我有一个包含字符串的文件(它实际上是一个字符串列表,但为了简单起见我跳过了它),它可以包含空格或为空,我们称之为 "color"。
例如:
{
...
"color": "Dull carmine pink"
...
}
我的查询需要能够执行以下操作:
- 搜索空值(包括和不包括)
- 搜索非空值(包括和不包括)
- 仅搜索并匹配整个短语(包括和不包括)。例如:
- 暗胭脂红 --> 匹配
- 胭脂红 --> 不匹配
- 与上一个相同,但带有通配符(包含和排除)。例如:
- ?ull carmine p* --> 匹配到 "Dull carmine pink"
- 暗胭脂红* -> 匹配 "Dull carmine pink"
- 等等
这几天我一直在用头撞墙,我尝试了几乎所有我能想到的查询类型。
在 this topic.
的帮助下,我只设法使它部分地与 span_near 查询一起工作
基本上我现在可以了:
搜索整个短语 with/without 像这样的通配符:
{
"span_near": {
"clauses": [
{
"span_term": {"color": "dull"}
},
{
"span_term": {"color": "carmine"}
},
{
"span_multi": {"match": {"wildcard": {"color": "p*"}}}
}
],
"slop": 0,
"in_order": true
}
}
通过简单的 must/must_not 查询来搜索 null 值(包括和不包括):
{
"must" / "must_not": {'exist': {'field': 'color'}}
}
问题:
我找不到进行独占跨度查询的方法。我能找到的唯一方法是 this。但它需要包含和排除字段,我只是想排除一些字段,所有其他字段都必须返回。是否有一些类似 "match_all":{} 的查询可以在 span_not 的包含字段中工作?或者也许是一个全新的、更优雅的解决方案?
我一个月前找到了解决方案,但我忘了 post 在这里。
我手头没有例子,但我会尽力解释。
问题是我试图查询的字段在查询之前被 elasticsearch 分析过了。有问题的分析器将它们除以空格等。这个问题的解决方案是以下两个之一:
1. 如果索引没有使用自定义映射。
(意思是如果您让 elasticsearch 在您添加字段时为您的字段动态创建适当的映射)。
在这种情况下,弹性搜索会自动创建一个名为“关键字”的文本字段的子字段。该子字段使用“关键字”分析器,在查询之前不以任何方式处理数据。
这意味着像这样的查询:
{
"query": {
"bool": {
"must": [ // must_not
{
"match": {
"user.keyword": "Kim Chy"
}
}
]
}
}
}
和
{
"query": {
"bool": {
"must": [ // must_not
{
"wildcard": {
"user.keyword": "Kim*y"
}
}
]
}
}
}
应该按预期工作。
但是对于默认映射,关键字字段很可能区分大小写。为了使其不区分大小写,您需要创建一个自定义映射,将小写(或大写)normalizer 应用于查询和关键字字段在匹配之前。
2。如果您使用自定义映射
与上面基本相同,但是您必须手动创建一个新的子字段(或字段),它使用关键字分析器(可能还有规范化器以使其不区分大小写)。
P.S. 据我所知,在 elasticsearch 中不再可能更改映射。这意味着您将必须使用适当的映射创建一个新索引,然后将您的数据重新索引到新索引。
我在尝试创建只能匹配整个短语但也允许使用通配符的查询时遇到了一些困难。
基本上我有一个包含字符串的文件(它实际上是一个字符串列表,但为了简单起见我跳过了它),它可以包含空格或为空,我们称之为 "color"。
例如:
{
...
"color": "Dull carmine pink"
...
}
我的查询需要能够执行以下操作:
- 搜索空值(包括和不包括)
- 搜索非空值(包括和不包括)
- 仅搜索并匹配整个短语(包括和不包括)。例如:
- 暗胭脂红 --> 匹配
- 胭脂红 --> 不匹配
- 与上一个相同,但带有通配符(包含和排除)。例如:
- ?ull carmine p* --> 匹配到 "Dull carmine pink"
- 暗胭脂红* -> 匹配 "Dull carmine pink"
- 等等
这几天我一直在用头撞墙,我尝试了几乎所有我能想到的查询类型。
在 this topic.
的帮助下,我只设法使它部分地与 span_near 查询一起工作基本上我现在可以了:
搜索整个短语 with/without 像这样的通配符:
{ "span_near": { "clauses": [ { "span_term": {"color": "dull"} }, { "span_term": {"color": "carmine"} }, { "span_multi": {"match": {"wildcard": {"color": "p*"}}} } ], "slop": 0, "in_order": true } }
通过简单的 must/must_not 查询来搜索 null 值(包括和不包括):
{ "must" / "must_not": {'exist': {'field': 'color'}} }
问题: 我找不到进行独占跨度查询的方法。我能找到的唯一方法是 this。但它需要包含和排除字段,我只是想排除一些字段,所有其他字段都必须返回。是否有一些类似 "match_all":{} 的查询可以在 span_not 的包含字段中工作?或者也许是一个全新的、更优雅的解决方案?
我一个月前找到了解决方案,但我忘了 post 在这里。 我手头没有例子,但我会尽力解释。
问题是我试图查询的字段在查询之前被 elasticsearch 分析过了。有问题的分析器将它们除以空格等。这个问题的解决方案是以下两个之一:
1. 如果索引没有使用自定义映射。
(意思是如果您让 elasticsearch 在您添加字段时为您的字段动态创建适当的映射)。
在这种情况下,弹性搜索会自动创建一个名为“关键字”的文本字段的子字段。该子字段使用“关键字”分析器,在查询之前不以任何方式处理数据。
这意味着像这样的查询:
{
"query": {
"bool": {
"must": [ // must_not
{
"match": {
"user.keyword": "Kim Chy"
}
}
]
}
}
} 和
{
"query": {
"bool": {
"must": [ // must_not
{
"wildcard": {
"user.keyword": "Kim*y"
}
}
]
}
}
}
应该按预期工作。
但是对于默认映射,关键字字段很可能区分大小写。为了使其不区分大小写,您需要创建一个自定义映射,将小写(或大写)normalizer 应用于查询和关键字字段在匹配之前。
2。如果您使用自定义映射
与上面基本相同,但是您必须手动创建一个新的子字段(或字段),它使用关键字分析器(可能还有规范化器以使其不区分大小写)。
P.S. 据我所知,在 elasticsearch 中不再可能更改映射。这意味着您将必须使用适当的映射创建一个新索引,然后将您的数据重新索引到新索引。