TL;DR - 如何检查其中之一和全部嵌套数组满足指定条件?
我有一个文档
。每个 document
都有一个嵌套的 outer
对象数组,它们本身有一个嵌套的 inner
对象列表。我需要对所有至少一个文档的外部
嵌套对象匹配的文档执行过滤器。当我说匹配时,我的意思是所有 outer
嵌套对象的inner
对象以某种方式匹配。这是一个示例映射以供引用;
{ "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"
}
}}}}}}
}
如果文档没有outer
/inner
对象,则认为匹配。但更糟糕的是,内部对象需要考虑以一种条件逻辑方式(例如 SQL 中的 CASE
)根据 type
进行不同的匹配。例如,如果 type
是术语 "Country"
那么 inner
对象将被认为匹配如果 匹配
是指定的国家代码,例如 ES
。文档可能具有不同类型
的内部
对象,并且不保证特定类型将存在。
来自命令式 (Java) 编程背景的我在弄清楚如何实现这种过滤方面遇到了难以置信的困难。我能想到的任何东西甚至都模糊地符合这种行为。到目前为止,我所拥有的只是过滤后的查询;
"filtered" : {
"query" : {
"match_all" : { }
},
"filter" : {
"bool" : {
"should" : {
"missing" : {
"field" : "outer.inner.type"
}
}}}}
}
那么,问题是……
我如何过滤到具有至少一个 outer
对象且具有所有 inner
对象匹配的文档基于内部
对象的类型
?
根据要求提供更多详细信息-
示例文档 JSON
{
"name":"First",
"outer":[
{
"inner":[
{"match":"ES","type":"Country"},
{"match":"Elite","type":"Market"}
]
},{
"inner":[
{"match":"GBR","type":"Country"},
{"match":"1st Class","type":"Market"},
{"match":"Admin","type":"Role"}
]
}
],
"lockVersion":0,"sourceId":"1"
}
如果我们要提供"1st Class"
市场和国家"GRB"
,上面的例子应该通过过滤器,因为两个 outer
对象中的第二个将被视为匹配,因为两个 inner
对象都匹配。但是,如果我们提供国家 "GRB"
和市场 "Elite"
那么我们将不会返回此文档,因为 outer
code> 对象会麻烦它们的 inner
对象完全匹配。如果我们希望第二个 outer
对象匹配,那么所有三个 inner
都需要匹配。请注意,在第三个inner
中有一个额外的type
。这会导致这样一种情况:如果存在一个类型,那么它需要匹配它else它不需要匹配,因为它缺席。
最佳答案
嵌套数组之一
让嵌套数组中的一个匹配某些条件变得非常简单。 nested filter如果嵌套对象数组中的任何一个与指定的内部过滤器匹配,则计算结果为匹配/真。例如,给定一个 outer
对象数组,其中一个对象的字段 match
的值为 "matching"
将考虑以下内容是的。
"nested": {
"path": "outer",
"filter": {
"term" : { "match" : "matching" }
}
}
如果 其中一个 嵌套的 outer
对象有一个名为 match
且值为 的字段,则以上内容将被视为真实/匹配“匹配”
。
所有嵌套数组
只有当数组中的所有嵌套对象匹配时才认为嵌套过滤器匹配更有趣。事实上,这是不可能的。但是考虑到如果只有一个嵌套对象与过滤器匹配就被认为是匹配的,我们可以颠倒逻辑并说“如果嵌套对象的没有 不匹配”实现我们所需要的。例如,给定一个嵌套的 outer.inner
对象数组,其中所有这些对象都有一个字段 match
,其值为 "matching"
,如下所示将被认为是真实的。
"not" : {
"nested": {
"path": "outer.inner",
"filter": {
"not" : {
"term" : { "match" : "matching" }
}
}
}
}
以上将被认为是真实的/匹配的,因为没有嵌套的outer.inner
对象不(双重否定)有名为 match
的字段,值为 "matching"
。当然,这与所有嵌套内部
对象具有匹配
字段且值为“匹配”
.
缺少任何嵌套对象
您无法使用传统的 missing filter 检查是否缺少包含嵌套对象的字段.这是因为嵌套对象实际上根本不在文档中,它们存储在其他地方。因此 missing filters将永远被认为是真实的。但是,您可以做的是检查 match_all
过滤器是否不返回这样的结果;
"not": {
"nested": {
"path": "outer",
"filter": {
"match_all": {}
}
}
}
如果 match_all
没有找到结果,则这被认为是正确的/匹配的。
关于arrays - Elasticsearch - 过滤其中(嵌套数组之一)和(所有嵌套数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32608969/