Elasticsearch:布尔值下的嵌套查询'应该'没有返回结果

时间:2015-02-07 22:11:01

标签: elasticsearch

我正在运行以下查询(为了清晰起见,它已缩短):

body : {
        query : {
            bool : {
                must : [
                    {
                        match : {
                            active : 1
                            }
                        },
                    ],
                should : [
                      {
                        term : {
                            apply : '2'
                            }
                        },
                      {
                        nested : {
                            path : 'items',
                            query : {
                                terms : {
                                    'items.product' : ["1","2"]
                                    }
                                }
                            }
                        }
                    ],
                minimum_should_match : 1
                }
            }
        }
    };

当我运行此查询时,我不会在should子句中撤回与嵌套查询匹配的文档;我只撤回符合第一个条件的文件。我究竟做错了什么?为什么术语查询不能根据输入项数组测试字段并返回结果?

当我将嵌套查询更改为match_all或将items.product字段与精确值匹配时,我会得到结果。

将嵌套查询更改为以下内容而不是当前嵌套查询(而其他所有内容保持不变)也不会给我带来任何结果。

 nested : {
        path : 'items',
        query : {
            bool : {
                must : [
                    {
                        terms : {
                            'items.product' : ["1","2"],            
                             minimum_should_match : 1
                            }
                        },                          
                    ]
                }
            }
         }

任何帮助都会非常感激 - 这已经让我疯了几天了!

1 个答案:

答案 0 :(得分:2)

已编辑以包含对索引映射的讨论

鉴于terms条件需要一个未分析的字段(根据文档here),我建议您验证您的索引是否具有专门的映射。例如:

{"mappings" : {
  "your_doc_type" : {
    "items" : {
      "type" : "nested",
      "properties" : {
        "product" : {"type" : "string", "index" : "not_analyzed"},
        ...
        ... Other properties of the nested object
        ...
      }
    },
    ...
    ... Mappings for the other fields in your document type
    ...
  }
}

这应该使terms能够在检查items.product时执行他们应该执行的操作。

我之前的怀疑是,您的查询中有其他内容(或许min_score)正在根据得分过滤掉结果,而该阈值正在清除符合items.product条件的文档但是由于潜在的Lucene评分模型而不是apply条件。换句话说,如果只满足should个查询的一个项目的文档的所有其他内容相同,那么符合"apply":"2"条件的文档的得分将高于items.product{"active":1, "apply":"2", "items" : [{"product": "3"}]} {"active":0, "apply":"2", "items" : [{"product": "3"}]} {"active":1, "apply":"3", "items" : [{"product": "3"}]} {"active":1, "apply":"3", "items" : [{"product": "1"}]} {"active":1, "apply":"3", "items" : [{"product": "2"}]} 的文档这是我的经验观察,用你的查询查询一个简单的小测试数据集。

测试数据集:

"hits" : [ {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1rIJ0nixSnh_cG",
  "_score" : 0.731233,
  "_source":{"active":1, "apply":"2", "items" : [{"product": "3"}]}
}, {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1sIJ0nixSnh_cK",
  "_score" : 0.4601705,
  "_source":{"active":1, "apply":"3", "items" : [{"product": "2"}]}
}, {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1sIJ0nixSnh_cJ",
  "_score" : 0.35959372,
  "_source":{"active":1, "apply":"3", "items" : [{"product": "1"}]}
} ]

根据查询中的条件,我们应该看到返回的三个文件 - 第一,第四和第五个文件。

apply

预期的文件回来了,但您可以看到第一个文档(should为2,符合{ "query" : {"filtered" : { "query" : {"match_all" : {}}, "filter" : {"bool" : { "must" : [ {"term" : {"active" : 1}} ], "should" : [ {"term" : {"apply" : "2"}}, {"nested" : { "path": "items", "query" : { "terms" : {"items.product" : ["1", "2"]} } }} ] }} }} } 查询的第一个标准)得分更高。

如果您的意图是这些条件不会影响文档的评分,而是将其用作简单的包含/排除标准,则可能需要切换到筛选的查询。类似的东西:

"hits" : [ {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1rIJ0nixSnh_cG",
  "_score" : 1.0,
  "_source":{"active":1, "apply":"2", "items" : [{"product": "3"}]}
}, {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1sIJ0nixSnh_cK",
  "_score" : 1.0,
  "_source":{"active":1, "apply":"3", "items" : [{"product": "2"}]}
}, {
  "_index" : "test",
  "_type" : "test",
  "_id" : "AUtrND1sIJ0nixSnh_cJ",
  "_score" : 1.0,
  "_source":{"active":1, "apply":"3", "items" : [{"product": "1"}]}
} ]

由于您现在正在指定过滤器,因此这些条件不应影响返回文档的评分,而只是确定文档是否完全符合结果集(然后独立于上述条件计算得分)。使用此筛选的查询,我的哑数据集的结果是:

should

现在所有退回文件的分数都相同,而不考虑query的哪一部分得到满足。

请注意,上面的match_all属性为{{1}} - 如果您的查询中有其他条件未在原始问题中显示,那么您需要相应地对其进行修改。