如何从Python中提高Easticsearch的查询精度?
如何通过使用Python包装器提高搜索结果的准确性?我的基本示例返回结果,但结果非常不准确 我正在Ubuntu 16上运行Elasticsearch 5.2,首先创建索引并添加一些文档,如:如何从Python中提高Easticsearch的查询精度?,python,
elasticsearch,Python,
elasticsearch,如何通过使用Python包装器提高搜索结果的准确性?我的基本示例返回结果,但结果非常不准确 我正在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',
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\u短语
查询而不是match
查询,以便将搜索词的顺序和接近度混合在一起。此外,您还可以添加一个小的slop
,以便使术语进一步分开或以不同的顺序排列。但术语顺序相同且距离较近的文档的排名将高于术语顺序不正确和/或距离较远的文档。试试看
"query": {
"match_phrase": {
"search_key": query,
"slop": 10
}
},
注意:
slop
是一个数字,指示您需要执行多少个搜索词才能登录文档中的词配置。在查询中,您可以使用match\u短语
查询,而不是match
查询,以便将搜索词的顺序和接近度混合在一起。此外,您还可以添加一个小的slop
,以便使术语进一步分开或以不同的顺序排列。但术语顺序相同且距离较近的文档的排名将高于术语顺序不正确和/或距离较远的文档。试试看
"query": {
"match_phrase": {
"search_key": query,
"slop": 10
}
},
注意:
slop
是一个数字,表示您需要执行多少搜索项才能登录到文档中的术语配置。很抱歉没有更仔细地阅读您的问题和下面加载的答案。我不想陷入泥潭,但我认为如果你对Elasticsearch本身的工作原理有更多的了解,就会更清楚
由于您在不指定任何索引和配置的情况下为文档编制索引,Elasticsearch将使用它提供的一些开箱即用的默认值。索引过程将首先使用标记化文档中的字段值,并在将其存储到索引中之前使用进行分析。标准标记器和分析器都是根据单词边界分割字符串的。因此,在索引时间结束时,搜索键
字段中的术语索引中有[“某些”、“特定”、“关键字”]
,而不是“某些特定关键字”
在搜索期间,匹配
查询使用称为术语频率/反向文档频率或TF/IDF的相似性算法进行控制。这种算法在一般的文本搜索中非常流行,并且有一个关于它的维基百科部分:。这里需要注意的是,你的术语在索引中出现的频率越高,它在相关性方面就越不重要<代码>某些、特定的
和关键字
出现在索引中的所有3个文档中,因此就elasticsearch而言,它们对文档在搜索结果中的相关性贡献甚微。由于A只包含这些术语,这就像在英文索引中有一个文档只包含the
,an
,A
。即使您搜索the
,an
,a
,它也不会显示为第一个结果。B的排名高于C,因为B较短,这会产生较高的范数值。该规范值在相关文档中进行了解释。就我而言,这是一种推测,但如果您使用API解释查询,我认为它确实是这样工作的
那么,回到你的需要,如何使精确匹配优于其他一切?当然,正如瓦尔所指出的那样,还有一个问题。另一种流行的方法,我个人更喜欢,是在名为
search\u key的嵌套字段中索引原始值。定义映射时,使用not\u analysisted
选项为原始值编制索引:搜索时只需增加此原始值。很抱歉没有更仔细地阅读您的问题和下面加载的答案。我不想陷入泥潭,但我认为如果你对Elasticsearch本身的工作原理有更多的了解,就会更清楚
由于您在不指定任何索引和配置的情况下为文档编制索引,Elasticsearch将使用它提供的一些开箱即用的默认值。索引过程将首先使用标记化文档中的字段值,并在将其存储到索引中之前使用进行分析。标准标记器和分析器都是根据单词边界分割字符串的。因此,在索引时间结束时,搜索键
字段中的术语索引中有[“某些”、“特定”、“关键字”]
,而不是“某些特定关键字”
在搜索期间,匹配
查询使用称为术语频率/反向文档频率或TF/IDF的相似性算法进行控制。这种算法在一般的文本搜索中非常流行,并且有一个关于它的维基百科部分:。这里需要注意的是,你的术语在索引中出现的频率越高,它在相关性方面就越不重要<代码>部分
,特定
,a