[英]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()
调用有问题吗?
很抱歉,您没有更仔细地阅读您的问题以及下面的已加载答案。 我不想陷入泥潭,但是如果您进一步了解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 。 这里要注意的重要一点是,您的术语出现在索引中的频率越高,其相关性就越不重要。 some
, specific
和keywords
出现在索引的所有3个文档中,因此就Elasticsearch而言,它们对文档在搜索结果中的相关性贡献很小。 由于A仅包含这些术语,因此就像在文档中仅包含英语索引中the
, an
, a
。 它不会显示为第一个结果,即使你搜索the
, an
, a
特别。 由于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.