我有以下查询为我的搜索添加模糊性。但是,我现在意识到匹配查询不考虑搜索字符串中单词的顺序,就像match_phrase那样。但是,我不能得到match_phrase给我模糊的结果。有没有办法告诉匹配考虑单词之间的顺序和距离?
{
"query": {
"match": {
"content": {
"query": "some search terms like this",
"fuzziness": 1,
"operator": "and"
}
}
}
}
答案 0 :(得分:15)
最终发现我需要使用span
个查询的组合,这些查询可以对模糊性和污点进行大量微调。我需要添加一个函数来手动标记我的短语并添加到"子句"以编程方式编译数组:
{"query":
{
"span_near": {
"clauses": [
{
"span_multi": {
"match": {
"fuzzy": {
"content": {
"fuzziness": "2",
"value": "word"
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"content": {
"fuzziness": "2",
"value": "another"
}
}
}
}
}
],
"slop": 1,
"in_order": "true"
答案 1 :(得分:1)
@econgineer优秀的帖子。
我想尝试使用我们正在处理的ES查询 - 但是我懒得继续使用JSON数据....
我认为这段代码有效...奇怪的是它导致jq抱怨,但ElasticSearch工作......
import json
import pprint
from collections import defaultdict
nested_dict = lambda: defaultdict(nested_dict)
query=nested_dict()
query['span_near']['clauses']=list()
query['slop']='1'
query['in_order']="true"
words=['what','is','this']
for w in words:
nest = nested_dict()
nest["span_multi"]["match"]["fuzzy"]["msg"]["fuzziness"]["value"]=w
nest["span_multi"]["match"]["fuzzy"]["msg"]["fuzziness"]["fuzziness"]="2"
json.dumps(nest)
query['span_near']['clauses'].append(json.loads(json.dumps(nest)))
pprint.pprint(json.loads(json.dumps(query)))
如果你通过
来美化输出cat t2.json | tr "\'" "\"" | jq '.'
您应该看到类似
的内容{
"in_order": "true",
"slop": "1",
"span_near": {
"clauses": [
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "what"
}
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "is"
}
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "this"
}
}
}
}
}
}
]
}
}
然后查询ES它只是一个普通的
curl --silent My_ES_Server:9200:/INDEX/_search -d @t2.json
非常感谢您的初步指导,我希望其他人能够发现这一点。
答案 2 :(得分:0)
确实,一个很好的问答。 我很惊讶这种“模糊短语匹配”没有开箱即用的支持。
这是一个经过测试的NodeJS代码,它在多搜索(msearch)的上下文中生成模糊短语匹配(多子句)查询块,但是对于单个搜索,它应该是相同的。
<强>用法:强>
let queryBody = [];
client.msearch({
body: queryBody
})
queryBody.push({ index: 'YOUR_INDEX' });
queryBody.push(createESFuzzyPhraseQueryBlock('YOUR PHRASE', 'YOUR_FIELD_NAME', 2)); // 2 <- fuzziness
功能:
const createESFuzzyPhraseClauseBlock = (word, esFieldName, fuzziness) => {
let clauseBlock = JSON.parse(
`{
"span_multi": {
"match": {
"fuzzy": {
"${esFieldName}": {
"fuzziness": "${fuzziness}",
"value": "${word}"
}
}
}
}
}`);
return clauseBlock;
};
const createESFuzzyPhraseQueryBlock = (phrase, esFieldName, fuzziness) => {
let clauses = [];
let words = phrase.split(' ');
words.forEach(word => clauses.push(createESFuzzyPhraseClauseBlock(word, esFieldName, fuzziness)));
let queryBlock =
{
"query":
{
"span_near": {
"clauses": clauses,
"slop": 1,
"in_order": "true"
}
}
};
return queryBlock;
};
答案 3 :(得分:0)
还考虑混合查询,对我来说基本查询看起来像这样-对于长度为2的短语,我使用了前缀查询,对于其余部分,我使用了模糊性设置为AUTO的匹配查询。