Elasticsearch-检查文档是否使用同义词中包含在查询中



我想构建一个应用程序,其中匹配需要至少在查询中包含文档中的每个令牌!

请注意与标准期望相比。因此,文档现在很小,而查询可能很长。示例:

文档:

"elastic super cool".

有效的查询匹配将为

"I like elastic things since elasticsearch is super cool"

我设法从弹性搜索中获取了匹配的令牌数量(另请参见https://groups.google.com/forum/?fromgroups=#topic/elasticsearch/ttjte52hxf8)。因此,在上面的示例3匹配(=文档的长度)将表示查询匹配。

但是如何将其与同义词结合?

假设"酷"的同义词将是"好","伟大"one_answers"好"。通过使用同义词令牌过滤器,我设法将同步添加到文档中的每个位置。

中的每个位置。

因此,以下四个文档在上面的查询中有3个令牌匹配:

"elastic super nice"
"elastic nice cool"
"nice good great"
"good great cool"

,但只有第一场比赛是有效的比赛!

我如何避免每个同义词匹配是一个匹配,尽管它们在文档中表示相同的令牌?

有什么想法如何解决这个问题?

我读到渗滤剂可能会解决这个问题,但是我仍然不确定perculator是否会按照我想要的方式使用同义词...

想法?

我假设您扩展了同义词。您可以使用脚本来计算匹配位置。

Elasticsearch Google Group with 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;
}

您可以在查询中将其用作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"
}
}

然后,您可以将" min_score"设置为1,而仅获取与给定字段中所有位置匹配的文档。

我希望这个解决方案是您需要的。

最新更新