对于ElasticSearch查询,我们希望以不同方式处理单词(即仅由字母组成的标记)和非单词。为此,我们尝试定义两个分析器,返回单词或非单词。
例如,我们有描述硬件商店产品的文档:
{
"name": "Torx drive T9",
"category": "screws",
"size": 2.5,
}
然后,用户将搜索" Torx T9"并希望找到这份文件。搜索T9过于通用,会产生太多不相关的产品。所以我们只想搜索“T9'术语,如果我们已经找到了' Torx'。
我们尝试创建这样的查询
{
"query": {
"bool": {
"must": {
"match: {
"name": {
"query": "Torx T9",
"analyzer": "words"
}
},
"should": {
"match: {
"name": {
"query": "Torx T9",
"analyzer": "nonwords"
}
}
}
}
}
这个想法是创建令牌过滤器来实现这一点很简单。例如:
"settings": {
"analysis": {
"filter": {
"words": {
"type": "pattern",
"pattern": "\\A\\p{L}*\\Z",
},
"nonwords": {
"type": "pattern",
"pattern": "\\P{L}",
}
}
}
但似乎并不是仅仅匹配模式的过滤器。相反,我们(ab)使用pattern_replace过滤器:
"settings": {
"analysis": {
"filter": {
"words": {
"type": "pattern_replace",
"pattern": "\\A((?=.*\\P{L}).*)",
"replacement": ""
},
"nonwords": {
"type": "pattern_replace",
"pattern": "\\A((?!.*\\P{L}).*)",
"replacement": ""
},
"nonempty": {
"type": "length",
"min":1
}
}
}
这将使用空令牌替换不需要的令牌,然后可以通过非空过滤器将其删除。这似乎有效,但所需的模式更加模糊。
有没有更好的方式表达这个?
答案 0 :(得分:1)
您可以使用default_operator尝试query-string-query作为" AND"为了你的要求。
例如,考虑您正在索引两个字符串" Torx驱动器T9"和#34;方形驱动器T9"。如果使用whitespace tokenizer进行索引,则字符串将被分析为以下标记
第一份文件:torx
,drive
和t9
。
第二份文件:square
,drive
和t9
。
然后使用查询字符串查询将文档与默认运算符匹配为AND将生成预期结果。
示例映射
{
"settings": {
"analysis": {
"analyzer": {
"whitespace": {
"type": "pattern",
"pattern": "\\s+"
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"name": {
"type": "string",
"analyzer": "whitespace"
}
}
}
}
}
示例查询
{
"query": {
"query_string": {
"default_field": "name",
"query": "Torx T9",
"default_operator": "AND"
}
}
}
只有当torx
和t9
出现在文档中时,此查询才会生成结果。