Arrays Elasticsearch-筛选其中(嵌套数组之一)和(所有嵌套数组)
TL;DR-如何检查嵌套数组的之一和全部是否符合指定标准 我有一个Arrays Elasticsearch-筛选其中(嵌套数组之一)和(所有嵌套数组),arrays,elasticsearch,nested,Arrays,elasticsearch,Nested,TL;DR-如何检查嵌套数组的之一和全部是否符合指定标准 我有一个文档。每个文档都有一个嵌套的外部对象数组,这些对象本身有一个嵌套的内部对象列表。我需要对所有文档执行筛选,其中文档的外部嵌套对象中至少有一个匹配。当我说match时,我的意思是所有的外部的嵌套对象的内部的对象以某种方式匹配。这里有一个示例映射供参考 { "document" : { "properties" : { "name" : { "type" : "string" },
文档
。每个文档
都有一个嵌套的外部
对象数组,这些对象本身有一个嵌套的内部
对象列表。我需要对所有文档执行筛选,其中文档的外部嵌套对象中至少有一个匹配。当我说match时,我的意思是所有的外部的嵌套对象的内部的对象以某种方式匹配。这里有一个示例映射供参考
{ "document" : {
"properties" : {
"name" : {
"type" : "string"
},
"outer" : {
"type" : "nested",
"properties" : {
"inner" : {
"type" : "nested",
"properties" : {
"match" : {
"type" : "string",
"index" : "not_analyzed"
},
"type" : {
"type" : "string",
"index" : "not_analyzed"
}
}}}}}}
}
如果文档没有外部
/内部
对象,则认为它匹配。但更糟糕的是,内部对象需要根据类型以一种条件逻辑方式(例如SQL中的CASE
)进行不同的匹配。例如,如果类型
是术语“国家”
,则如果匹配
是指定的国家代码,例如ES
,则内部
对象将被视为匹配。文档可能具有不同类型的内部对象,并且不能保证特定类型的存在
来自命令式(Java)编程背景的我在弄清楚如何实现这种过滤方面遇到了令人难以置信的困难。我想不出哪怕是模糊地符合这种行为的。到目前为止,我所拥有的只是经过过滤的查询
"filtered" : {
"query" : {
"match_all" : { }
},
"filter" : {
"bool" : {
"should" : {
"missing" : {
"field" : "outer.inner.type"
}
}}}}
}
所以,问题是
如何根据内部对象的类型匹配,筛选到至少有一个外部对象且所有内部对象的文档
如有需要,请提供更多详细信息-
示例文档JSON
如果我们要提供“一级”市场和国家“GRB”
,则上述示例应通过过滤器,因为两个外部对象中的第二个将被视为匹配,因为两个内部对象都匹配。但是,如果我们提供了country country“GRB”
和market“Elite”
,那么我们将不会返回此文档,因为外部对象都不会对其内部对象进行整体匹配。如果我们希望第二个外部
对象匹配,那么所有三个内部
都需要匹配。请注意,在第三个内部
中有一个额外的类型
。这会导致一种情况,即如果存在类型,则它需要有一个匹配项,否则它不需要匹配,因为它不存在 好吧,这是一个愚蠢的问题,但这个查询似乎满足了您的要求:
POST /test_index/_search
{
"query": {
"filtered": {
"filter": {
"nested": {
"path": "outer",
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "outer.inner",
"filter": {
"bool": {
"must": [
{ "term": { "outer.inner.type": "Market" } },
{ "term": { "outer.inner.match": "1st Class" } }
]
}
}
}
},
{
"nested": {
"path": "outer.inner",
"filter": {
"bool": {
"must": [
{ "term": { "outer.inner.type": "Country" } },
{ "term": { "outer.inner.match": "GBR" } }
]
}
}
}
}
]
}
}
}
}
}
}
}
下面是我用来测试它的一些代码:
如果您需要一些逻辑解释,请告诉我;它有点复杂。嵌套数组的一种
让
中的一个
嵌套数组与某些条件匹配,结果非常简单。如果任何嵌套对象数组与指定的内部过滤器匹配,则A的计算结果为matching/true。例如,给定一个外部
对象数组,其中一个对象有一个字段match
,其值为“matching”
,则认为以下为真
"nested": {
"path": "outer",
"filter": {
"term" : { "match" : "matching" }
}
}
"not" : {
"nested": {
"path": "outer.inner",
"filter": {
"not" : {
"term" : { "match" : "matching" }
}
}
}
}
如果嵌套的外部
对象中有一个名为match
的字段的值为“matching”
,则上述内容将被视为真实/匹配
所有嵌套数组
只有当数组匹配中的所有嵌套对象更有趣时,才将嵌套过滤器视为匹配。事实上,这是不可能的。但是,如果只有一个嵌套对象与过滤器匹配,则认为是匹配的,那么我们可以反转逻辑,说“如果没有嵌套对象的不匹配”,以实现我们所需要的。例如,给定一个嵌套的outer.internal
对象数组,其中所有这些对象都有一个字段match
,其值“matching”
,则认为以下为真
"nested": {
"path": "outer",
"filter": {
"term" : { "match" : "matching" }
}
}
"not" : {
"nested": {
"path": "outer.inner",
"filter": {
"not" : {
"term" : { "match" : "matching" }
}
}
}
}
上述内容将被视为真实/匹配,因为嵌套的外部对象中无。内部对象不(双负)有一个名为match
的字段,其值为“matching”
。当然,这与所有嵌套的内部对象的相同,这些对象都有一个字段match
,其值为“matching”
缺少任何嵌套对象
无法使用传统方法检查是否缺少包含嵌套对象的字段。这是因为嵌套对象实际上根本不在文档中,而是存储在其他地方。因此,将始终被认为是正确的。但是,您可以做的是检查match\u all
过滤器是否不返回这样的结果
"not": {
"nested": {
"path": "outer",
"filter": {
"match_all": {}
}
}
}
如果match\u all
未发现任何结果,则认为这是正确的/匹配的。您可以发布一些示例数据,可能是要点或其他内容吗?它需要包括足够的种类,以涵盖您的各种情况。我想我可能知道如何解决这个问题,但我不想花一上午的时间构建虚拟数据来测试它。@SloanAhrens-我已经发布了一个示例文档,其中包含一些细节,如果这还不够,请让我知道,我会再添加一些示例。在上面的问题中,我实际上没有使用生产数据/映射,因此我必须手动转换数据以匹配问题。不,我认为这样做了。很抱歉,我的回复太晚,感谢您的帮助,但这不会找到没有任何外部对象的结果。此外,由于我们无法确定特定的类型肯定存在,因此无法找到