Elasticsearch和条款过滤器和执行模式

时间:2015-12-15 18:48:49

标签: elasticsearch

我对如何实现与所有提供的条款匹配的过滤查询失去了理智,而不是'任何',基本上'和'vs'或'。

鉴于我有一个(非常简化的版本)文件:

{
    "content": {
        "tags": [
            {
                "tag": "Express",
                "type": "other"
            },
            {
                "tag": "Baking",
                "type": "other"
            }
        ]
    }
}

目前我有以下搜索内容:

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": ["Express", "Baking"],
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}

我知道这会查找任何包含'Express'的文档,并且还会添加任何包含'Baking'的文档。我需要的是一个只匹配同时存在两个标签的文档的过滤器。

我已经阅读了文档,我对它们的理解是我需要将"execution": "and"添加到过滤器中

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": ["Express", "Baking"],
                                    "execution": "and"
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}

可悲的是,这匹配了0个文件,当我知道其中有28个文件时。

我的content.tags.tag字段未被分析,content.tags有许多嵌套对象,如上所述,所以我理解它意味着它必须包含每个标记之一,但似乎不是这样的。

任何人都知道如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

您要求的是包含术语"Express""Baking"的嵌套文档,该文档与您列出的(父)文档不匹配。它有一个与第一个术语匹配的嵌套文档,以及与第二个术语匹配的另一个嵌套文档,但没有与两者匹配的嵌套文档。正如@Frederick指出的那样,你的第二个查询无论如何都无法在Es 2.0中运行。

另一方面,当我尝试你的查询时,无论如何我都没有得到任何结果,因为你的空查询子句什么都不匹配。但是当我删除它时,文档被返回,这是一个匹配任一术语但不是两者都匹配的文档。 (如果"execution": "and"没有被忽略,它就不会返回任何文件。)

无论如何,这听起来像是你要求的:找到一个包含符合这两个术语的嵌套文档的父文档:

POST /test_index/_search
{
   "filter": {
      "bool": {
         "must": [
            {
               "nested": {
                  "path": "content.tags",
                  "filter": {
                     "term": {
                        "content.tags.tag": "Express"
                     }
                  }
               }
            },
            {
               "nested": {
                  "path": "content.tags",
                  "filter": {
                     "term": {
                        "content.tags.tag": "Baking"
                     }
                  }
               }
            }
         ]
      }
   }
}

以下是我用来测试所有这些的一些代码(在ES 2.1中):

http://sense.qbox.io/gist/e375721509acbb5170e07eb969ea4409921f42d3

答案 1 :(得分:1)

使用两个不同的必须条件

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": "Banking"
                                }
                            }
                        }
                    },"nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": "Express"
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}