use*_*793 5 lucene fuzzy-search synonym elasticsearch
我想构建一个应用程序,其中匹配要求文档中的每个标记至少包含一次!
请注意其与标准期望相反.所以文档现在相当小,而查询可能很长.例:
文献:
"elastic super cool".
Run Code Online (Sandbox Code Playgroud)
有效的查询匹配将是
"I like elastic things since elasticsearch is super cool"
Run Code Online (Sandbox Code Playgroud)
我设法从弹性搜索中获得匹配令牌的数量(另请参阅https://groups.google.com/forum/?fromgroups=#!topic/elasticsearch/ttJTE52hXf8).因此在上面的例子中,3个匹配(=文档长度)意味着查询匹配.
但是我怎样才能将它与同义词结合起来???
假设"酷"的同义词将是"好","好"和"好".通过使用同义词标记过滤器,我设法将同义词添加到文档中的每个位置.
因此,以下四个文档每个都有上述查询的3个标记匹配:
"elastic super nice"
"elastic nice cool"
"nice good great"
"good great cool"
Run Code Online (Sandbox Code Playgroud)
但只有第一场比赛是有效的比赛!
我怎样才能避免每个同义词匹配计为一个匹配,尽管它们代表文档中的相同标记?
有任何想法如何解决这个问题?
我读到过滤器可能会解决这个问题,但我仍然不确定打击器是否会按照我想要的方式使用同义词...
想法?
我假设你扩展了同义词。您可以使用脚本来计算匹配位置。
Elasticsearch Google Group 提供 Vineeth Mohan 的解决方案
我将他的脚本改编为原生脚本,返回 0 到 1 之间的数字,表示字段中匹配位置的比率。我对其进行了一些调整,以便每个查询仅匹配一个位置
您需要一个包含仓位数量的字段,例如使用token_count来实际计算仓位数量
@Override
public Object run()
{
IndexField indexField = this.indexLookup().get(field);
Long numberOfPositions = ((ScriptDocValues.Longs) doc().get(positionsField)).getValue();
ArrayList<Integer> positions = new ArrayList<Integer>();
for (String term : terms)
{
Iterator<TermPosition> termPos = indexField.get(term, IndexLookup.FLAG_POSITIONS | IndexLookup.FLAG_CACHE)
.iterator();
while (termPos.hasNext())
{
int position = termPos.next().position;
if (positions.contains(position))
{
continue;
}
positions.add(position);
// if the term matches multiple positions, only a new position should count
break;
}
}
return positions.size() * 1.0 / numberOfPositions;
}
Run Code Online (Sandbox Code Playgroud)
您可以在查询中将其用作 function_score 脚本。
{
"function_score": {
"query": {
"match": {
"message": "I like elastic things since elasticsearch is super cool"
}
},
"script_score": {
"params": {
"terms": [
"I",
"like",
"elastic",
"things",
"since",
"elasticsearch",
"is",
"super",
"cool"
],
"field": "message",
"positions_field": "message.pos_count"
},
"lang": "native",
"script": "matched_positions_ratio"
},
"boost_mode": "replace"
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以将“min_score”设置为 1,并且仅获取与给定字段中的所有位置匹配的文档。
我希望这个解决方案是您所需要的。
| 归档时间: |
|
| 查看次数: |
714 次 |
| 最近记录: |