我在wildcard query search中遇到了一些问题。
我的目的是,如果我搜索word1 word2 word3
,我会找到所有的结果,可以有前缀和后缀之前和之后的每个词组成整个字符串。
我的索引结构是:
{
"my_index": {
"aliases": {},
"mappings": {
"properties": {
"attributes": {
"properties": {
"name": {
"properties": {
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
}
}
}
},
"settings": {
...
}
}
}
所以我有一个字段attributes.name
(文本),我想匹配值。
我的索引包含attributes.name
值的对象:
word1
,word1suffix
,word1 word2
,word1 word2suffix
word1 word2 word3
。
在运行搜索之前,我在内部在每个单词之前和之后添加通配符:word1 word2 word3
=> *word1* *word2* *word3*
然后我运行这个查询:
{
"size": 10,
"index": "my_index",
"body": {
"query": {
"bool": {
"should": [
{
"wildcard": {
"attributes.name.value": {
"value": "*word1* *word2* *word3*",
"rewrite": "constant_score"
}
}
}
],
"must": [],
"minimum_should_match": 1
}
}
},
"explain": false
}
我面临的奇怪的事情是,即使在索引中我有一个名为word1 word2 word3
的对象,我也无法通过这种搜索找到它(我知道在这种情况下,最好是一个 match_phrase 或 term 查询,但这只是为了理解为什么这个简单的情况不起作用)。
如果我试着用更少的词,比如:
*word1*
,我找到了word1
,word1suffix
,word1 word2
和word1 word2suffix
*word1* *word2*
,我发现word1 word2
和word1 word2suffix
*word1* *word2* *word3*
,无
因此,这种奇怪的行为似乎始于我搜索包含太多单词的结果。
只是为了调试,我的值以这种方式存储在索引中:
{
"attributes": {
"name": [{
"value": "word1 word2 word3"
}],
}
}
**最后一个考虑:**我设法找到word1 word2 word3
通过搜索字段attributes.name.value.keyword
(我认为.keyword
是自动生成的索引中的每一个文本字段),而不是attributes.name.value
。问题是,如果我使用.keyword
,分析器不工作,所以我认为这不是一个好的解决方案。
1条答案
按热度按时间h79rfbju1#
重复查询基于模式工作,因此它会将整个查询视为一个模式,因此当您添加多个单词时可能会不匹配。
你有两个选择:
首先是使用
query_string
类型的查询,如下图所示,您可以根据需求将default_operator
的值设置为AND
或OR
。这将仅在内部创建bool
查询:其次,您可以在
must
中为AND
查询和在should
中为OR
查询条件设置多个wildcard
查询:更新
我通过搜索字段
attributes.name.value.keyword
(我认为.keyword
是在每个文本字段的索引中自动生成的)而不是attributes.name.value
找到了word1 word2 word3
。问题是,如果我使用.keyword
,分析器不工作,所以我认为这不是一个好的解决方案。是的,如果你没有配置
mapping
,那么弹性将自动为每个字段创建Map,如果字段被发现为text
类型,那么它也会创建一个keyword
类型的内部字段。它正在工作,因为
keyword
字段不应用任何分析器,它会查找精确匹配。如果您尝试wildcard
查询attributes.name.value.keyword
字段与多个术语,那么它将工作,但它是区分大小写的。所以如果你有像word1 word2 word3
这样的字段值,那么*word1* *word2* *word3*
这个查询会工作,但是*Word1* *word2* *word3*
这个查询不会工作。(W
是大写的)。为什么
text
类型字段不工作?因为
wildcard
查询是术语级查询,并且在查询时不应用任何analyzer
。它会将你的整个查询视为一个模式。您正在匹配text
类型字段上的查询,该字段在索引时使用standard
分析器,并将文本标记为多个术语和索引,因此它适用于一个术语而不是多个术语。性能影响
不建议使用以
*
或?
开头的URL,因为它会影响搜索性能。下面是一个文件中提到的警告:避免以 * 或?这会增加查找匹配项所需的迭代次数,并降低搜索性能。