繁体   English   中英

如何从Python提高Easticsearch的查询准确性?

[英]How to improve query accuracy of Easticsearch from Python?

如何使用Python包装器提高Elasticsearch的搜索结果准确性? 我的基本示例返回结果,但是结果非常不准确。

我在Ubuntu 16上运行Elasticsearch 5.2,首先创建索引并添加一些文档,例如:

es = Elasticsearch()
# Document A
es.index(
    index='my-test-index',
    doc_type='text',
    body=dict(
        search_key='some specific keywords',
        weight=1.0,
        data='blah1',
    ),
)
# Document B
es.index(
    index='my-test-index',
    doc_type='text',
    body=dict(
        search_key='some other specific keywords',
        weight=1.0,
        data='blah2',
    ),
)
# Document C
es.index(
    index='my-test-index',
    doc_type='text',
    body=dict(
        search_key='some other very long text that is very different yet mentions the word specific and keywords',
        weight=1.0,
        data='blah3',
    ),
)

然后,我查询它:

es = Elasticsearch()
es.indices.create(index='my-test-index', ignore=400)
query = 'some specific keywords'
results = es.search(
    index='my-test-index',
    body={
        'query':{
            "function_score": {
                "query": {  
                    "match": {
                        "search_key": query
                    }
                },
                "functions": [{
                    "script_score": { 
                        "script": "doc['weight'].value"
                    }
                }],
                "score_mode": "multiply"
            }
        },
    }
)

尽管返回了所有结果,但它以文档B,C,A的顺序返回它们,而我希望它们以文档A,B,C的顺序返回,因为尽管所有文档都包含我所有的关键字,但只有第一个是完全匹配。 我希望C可以排在最后,因为即使它包含我所有的关键字,它也包含很多我没有明确搜索的绒毛。

当我为更多条目建立索引时,此问题会加重。 搜索返回的所有内容甚至都包含来自我的查询的单个关键字,并且似乎对它们的权重都相同,从而导致随着索引的增加搜索结果变得越来越不准确。

这使得Elasticsearch几乎毫无用处。 反正有我可以解决吗? 我的search()调用有问题吗?

在您的查询中,可以使用match_phrase查询而不是match查询,以便将搜索词的顺序和接近程度match_phrase 此外,您可以添加一个小的slop ,以使术语可以进一步分开或以不同的顺序排列。 但是,术语顺序相同且相距较近的文档将比术语顺序不合和/或相距较远的文档排名更高。 试试看

            "query": {  
                "match_phrase": {
                    "search_key": query,
                    "slop": 10
                }
            },

注意: slop是一个数字,指示您需要执行多少次搜索才能落入文档中存在的术语配置。

很抱歉,您没有更仔细地阅读您的问题以及下面的已加载答案。 我不想陷入泥潭,但是如果您进一步了解Elasticsearch本身的工作原理,那将会更加清楚。

因为您在不指定任何索引和映射配置的情况下为文档建立索引,所以Elasticsearch将使用它提供的一些默认值。 索引过程将首先使用标准标记器将文档中的字段值标记化 ,然后使用标准分析器对其进行分析,然后再将它们存储在索引中。 标准令牌生成器和分析器均通过根据单词边界拆分字符串来工作。 因此,在索引时间结束时,您在索引中对search_key字段中的术语所search_key["some", "specific", "keywords"] ,而不是"some specific keywords"

在搜索期间, match查询使用称为术语频率/文档反向频率或TF / IDF的相似性算法控制相关性 通常,此算法在文本搜索中非常流行,并且上面有一个Wikipedia部分: https : //en.wikipedia.org/wiki/Tf%E2%80%93idf 这里要注意的重要一点是,您的术语出现在索引中的频率越高,其相关性就越不重要。 somespecifickeywords出现在索引的所有3个文档中,因此就Elasticsearch而言,它们对文档在搜索结果中的相关性贡献很小。 由于A仅包含这些术语,因此就像在文档中仅包含英语索引中theana 它不会显示为第一个结果,即使你搜索theana特别。 由于B较短,因此B的排名高于C,这会产生较高的范数值。 相关文档中对此标准值进行了说明。 就我而言,这只是一个推测,但是如果您使用explain API解释查询,则我认为这样做确实可行。

那么,回到您的需求,如何在所有其他方面都支持完全匹配? 正如Val所指出的,当然有match_phrase查询。 我个人更喜欢这样做的另一种流行方法是在定义映射时使用not_analyzed选项在称为search_key.raw的嵌套字段中为原始值编制索引: https : not_analyzed /guide/current/mapping-intro.html#_index_2 ,只需在搜索时增加此原始值即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM