对于 ElasticSearch 查询,我们希望以不同的方式处理单词(即仅由字母组成的标记)和非单词。为此,我们尝试定义两个分析器,返回单词或非单词。
例如,我们有描述五金店产品的文档:
{
"name": "Torx drive T9",
"category": "screws",
"size": 2.5,
}
然后,用户将搜索“Torx T9”并期望找到此文档。搜索 T9 会过于通用,并且会提供太多不相关的产品。因此,如果我们已经找到“Torx”,我们只想搜索“T9”术语。
我们尝试创建一个这样的查询
{
"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
}
}
}
这会将不需要的标记替换为空标记,然后可以通过非空过滤器将其删除。这似乎可行,但所需的模式更加模糊。
有没有更好的方式来表达这一点?