gpt4 book ai didi

使用 lucene 模糊运算符时,Elasticsearch 查询和过滤器会给出不同的文档计数

转载 作者:行者123 更新时间:2023-11-29 02:53:30 26 4
gpt4 key购买 nike

使用 ElasticSearch v1.7.2 和相当大的索引,我得到了以下两个搜索的不同文档计数,它们在 query_string 中使用模糊搜索。

查询:

{
"query": {
"query_string": {
"query": "rapt~4"
}
}
}

过滤器:

{
"filter": {
"query": {
"query_string": {
"query": "rapt~4"
}
}
}
}

过滤器给出的结果比查询大约 5%。为什么文档计数会不同?是否有我可以指定的选项来使它们保持一致?

请注意,这种不一致只会在我使用中等大小的数据集时发生。我已尝试将几个 (<10) 个匹配过滤器但不匹配查询的文档插入到一个干净的集群中,之后我的查询和过滤器都成功地确实匹配了所有文档。但是,在单个索引、单个类型和数百个文档的集群中,我开始看到差异。

使用 explain=true 选项,query 分数似乎是使用 Practical Scoring Function 计算的.该解释提供了有关提升、queryNorm、idf 和术语权重的信息。相比之下,filter 解释仅报告 Practical Scoring Function 的 boost 和 queryNorm 组件,而不是 idf 或 term weights。

下面是带有解释的回复示例。请注意,我已经从我的示例命中中删除了许多字段并简化了内容,因此除了匹配的词(在本例中为“事实”)之外,解释中的术语频率将与实际内容不匹配。这些响应是针对相同 事件的。我的问题是过滤器响应中包含了查询响应中未包含的其他匹配项。他们的解释看起来完全相同。

查询:

curl -XPOST "http://localhost:9200/index-name/example-type/_search" -H "Content-Type: application/json" -d'{"query":{"query_string":{"query":"rapt~"}},"explain":true}'

和查询响应:

{
"_source": {
"type": "example",
"content": "to the fact that"
},
"_explanation": {
"value": 0.10740301,
"description": "sum of:",
"details": [
{
"value": 0.10740301,
"description": "weight(_all:fact^0.5 in 465) [PerFieldSimilarity], result of:",
"details": [
{
"value": 0.10740301,
"description": "score(doc=465,freq=2.0), product of:",
"details": [
{
"value": 0.11091774,
"description": "queryWeight, product of:",
"details": [
{
"value": 0.5,
"description": "boost"
},
{
"value": 7.303468,
"description": "idf(docFreq=68, maxDocs=37706)"
},
{
"value": 0.03037399,
"description": "queryNorm"
}
]
},
{
"value": 0.96831226,
"description": "fieldWeight in 465, product of:",
"details": [
{
"value": 1.4142135,
"description": "tf(freq=2.0), with freq of:",
"details": [
{
"value": 2,
"description": "termFreq=2.0"
}
]
},
{
"value": 7.303468,
"description": "idf(docFreq=68, maxDocs=37706)"
},
{
"value": 0.09375,
"description": "fieldNorm(doc=465)"
}
]
}
]
}
]
}
]
}
}

过滤器:

curl -XPOST "http://localhost:9200/index-name/example-type/_search" -H "Content-Type: application/json" -d'{"query":{"filtered":{"filter":{"fquery":{"query":{"query_string":{"query":"rapt~"}}}}}},"explain":true}'

并过滤响应:

{
"_source": {
"type": "example",
"content": "to the fact that"
},
"_explanation": {
"value": 1,
"description": "ConstantScore(cache(+_type:example-type +org.elasticsearch.index.search.nested.NonNestedDocsFilter@737a6633)), product of:",
"details": [
{
"value": 1,
"description": "boost"
},
{
"value": 1,
"description": "queryNorm"
}
]
}
}

当我将过滤器包装在一个常量分数查询中时,我得到了与过滤器完全相同的一组结果(同样,多于查询),但解释看起来更清晰:

恒定分数查询包装过滤器:

curl -XPOST "http://localhost:9200/index-name/example-type/_search" -H "Content-Type: application/json" -d'{"query":{"constant_score":{"filter":{"query":{"query_string":{"query":"rapt~"}}}}},"explain":true}'

和常量分数查询包装过滤器响应:

{
"_source": {
"type": "example",
"content": "to the fact that"
},
"_explanation": {
"value": 1,
"description": "ConstantScore(QueryWrapperFilter(_all:rapt~2)), product of:",
"details": [
{
"value": 1,
"description": "boost"
},
{
"value": 1,
"description": "queryNorm"
}
]
}
}

因为过滤器返回的结果比查询更多,我的猜测是实用评分函数最终对与查询匹配的文档评分为 0。但是,对于“匹配"查询,评分函数的任何组成部分都不应为零。

编辑:我在一个由 238 个文档组成的小集群上重新创建了这个问题(请注意,文档的内容是从在维基百科文本上训练的 ngram 语言模型生成的。)。我已经发布了 clusterjson events在保管箱上。要查看此数据的问题,请运行以下查询,它返回 id=138 的事件:

{
"explain": true,
"query": {
"bool": {
"must_not": [
{
"query_string": {
"query": "rap~",
"fields": [
"body"
]
}
}
],
"must": [
{
"constant_score": {
"filter": {
"query": {
"query_string": {
"query": "rap~",
"fields": [
"body"
]
}
}
}
}
}
]
}
}
}

最佳答案

在 Elasticsearch 之前 Elasticsearch 5.x 版本中,顶层的filter 表示post_filter .后过滤器通常仅在使用聚合时才相关。

从 Elasticsearch 5.0(及更高版本)开始,您必须明确说明 post_filter 以避免这种混淆。

因此,不同之处在于您的热门查询实际上将结果限制为一组匹配文档。后过滤器有效地匹配所有内容,然后仅从命中中删除结果而不影响计数。

...it appears that the query score is computed using...

查询总是计算分数,它们旨在帮助根据项目的相关性(分数)对项目进行正确排序。过滤器从不计算分数;过滤器用于纯 bool 逻辑,不影响包含/排除之外的“相关性”。

公平地说,您可以在 Elasticsearch 1.x 中以多种方式将任何查询转换为过滤器(在 2.x 中,所有查询在正确的上下文中也是过滤器!),但我倾向于使用 fquery 。如果你这样做,那么你应该得到相同的结果:

作为查询:

{
"query": {
"query_string": {
"query": "rapt~"
}
}
}

作为过滤器:

{
"query": {
"filtered": {
"filter": {
"fquery": {
"query": {
"query_string": {
"query": "rapt~"
}
}
}
}
}
}
}

在 ES 2.x 中,过滤器也简化了(并且查询没有改变):

{
"query": {
"bool": {
"filter": {
"query_string": {
"query": "rapt~"
}
}
}
}
}

关于使用 lucene 模糊运算符时,Elasticsearch 查询和过滤器会给出不同的文档计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34635815/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com