在我的Elasticsearch索引中,我的文档在同一位置有多个令牌。
当我在每个位置匹配至少一个令牌时,我想要取回一份文件。 令牌的顺序并不重要。 我怎么能做到这一点?我使用Elasticsearch 0.90.5。
示例:
我索引这样的文档。
{
"field":"red car"
}
我使用同义词令牌过滤器,在与原始令牌相同的位置添加同义词。 所以现在在现场,有2个职位:
我现在的解决方案:
为了确保所有位置都匹配,我也将索引最大位置。
{
"field":"red car",
"max_position": 2
}
我有一个自定义的相似性,它从DefaultSimilarity扩展并返回1 tf(),idf()和lengthNorm()。得分是该字段中匹配条款的数量。
查询:
{
"custom_score": {
"query": {
"match": {
"field": "a car is an automobile"
}
},
"_script": "_score*100/doc[\"max_position\"]+_score"
},
"min_score":"100"
}
我的解决方案出现问题:
上述搜索不应与文档匹配,因为查询字符串中没有标记“red”。但它匹配,因为Elasticsearch将汽车和汽车的匹配计算为两个匹配,得分为2,这导致脚本得分为102,满足“min_score”。
答案 0 :(得分:0)
如果您需要保证与查询字词 100%匹配,则可以使用minimum_should_match
。这是更常见的情况。
很遗憾,在您的情况下,您希望提供索引字词的100%匹配。为此,您必须下拉到Lucene级别并编写自定义(java - here's boilerplate you can fork)Similarity类,因为您需要访问未向Query DSL公开的低级索引信息:
在查询记分员中扫描的每个文档/字段:
然后您的自定义相似度(您甚至可以扩展DefaultSimilarity)将需要检测术语匹配< 总条款并将其得分乘以零。
由于查询和索引时间分析已经在此评分级别进行,因此索引术语的总数将已扩展为包含同义词,查询术语也应如此,从而避免误报“a car是上面的汽车“问题。