Rud*_*haw 13 arrays nested elasticsearch
TL; DR -我该如何检查是否之一的和所有的嵌套阵列符合规定的标准是什么?
我有一个document.每个document都有一个嵌套outer对象数组,它们自己有一个嵌套inner对象列表.我需要对文档嵌套对象中至少有一个outer匹配的所有文档执行过滤.当我说的比赛,我的意思是所有的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"
}
}}}}}}
}
Run Code Online (Sandbox Code Playgroud)
如果文档没有outer/ inner对象,则认为它匹配.但是为了使事情变得更糟,需要根据type一种条件逻辑方式(例如CASE在SQL中)来考虑内部对象的不同匹配.例如,如果type是该术语"Country"则inner对象将被认为是匹配,如果match是一个指定的国家代码,例如ES.文档可能具有inner不同的对象,type并且不保证将存在特定类型.
来自命令式(Java)编程背景我在弄清楚如何实现这种过滤方面遇到了令人难以置信的麻烦.没有什么我能想到甚至模糊地匹配这种行为.到目前为止,我所拥有的只是过滤后的查询;
"filtered" : {
"query" : {
"match_all" : { }
},
"filter" : {
"bool" : {
"should" : {
"missing" : {
"field" : "outer.inner.type"
}
}}}}
}
Run Code Online (Sandbox Code Playgroud)
所以,问题是......
如何才能筛选到谁拥有的文件至少一个 outer具有对象的所有 inner匹配基于对象type的inner对象?
进一步详情按要求 -
{
"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"
}
Run Code Online (Sandbox Code Playgroud)
如果我们要提供"1st Class"市场和国家/地区,上面的示例应该通过过滤器,"GRB"因为两个outer对象中的第二个将被视为匹配,因为两个inner对象都匹配.但是,如果我们提供了国家/地区"GRB"和市场,"Elite"那么我们就不会返回此文档,因为这两个outer对象都不会打扰它们的inner对象完全匹配.如果我们想要outer匹配第二个对象,则所有三个inner都需要匹配.请注意,type第三个是额外的inner.这导致如果存在类型,则需要匹配它的情况否则它不需要匹配,因为它不存在.
Rud*_*haw 15
具有的一个嵌套数组满足某种条件被证明是非常简单的.甲嵌套滤波器如果任何嵌套对象的阵列的匹配指定内的过滤器的计算结果为匹配/真.例如,给定一个outer对象数组,其中一个对象的字段match具有值,"matching"则以下内容将被视为true.
"nested": {
"path": "outer",
"filter": {
"term" : { "match" : "matching" }
}
}
Run Code Online (Sandbox Code Playgroud)
如果其中一个嵌套outer对象具有一个名为matchvalue 的字段,则上述内容将被视为true/matching "matching".
如果数组中的所有嵌套对象匹配更有趣,则仅将嵌套过滤器视为匹配.事实上,这是不可能的.但是如果只有一个嵌套对象与过滤器匹配,则认为它是匹配的,我们可以反转逻辑并说"如果没有嵌套对象不匹配"来实现我们需要的东西.例如,给定一个嵌套outer.inner对象数组,其中所有这些对象都有一个match具有该值"matching"的字段,以下内容将被视为true.
"not" : {
"nested": {
"path": "outer.inner",
"filter": {
"not" : {
"term" : { "match" : "matching" }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以上将被认为是真/匹配,因为没有嵌套outer.inner对象没有(双负)有一个match用值调用的字段"matching".当然,这与具有值的字段的所有嵌套inner对象相同.match"matching"
您无法使用传统的缺失过滤器检查是否缺少包含嵌套对象的字段.这是因为,嵌套的对象实际上并不在该文件可言,它们存储在别处.因为这样的缺失过滤器将始终被视为真实.但是,您可以检查match_all过滤器是否返回没有这样的结果;
"not": {
"nested": {
"path": "outer",
"filter": {
"match_all": {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果match_all没有找到结果,则认为这是真/匹配.
好吧,这很糟糕,但是这个查询似乎可以满足您的需求:
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" } }
]
}
}
}
}
]
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我用来测试它的一些代码:
http://sense.qbox.io/gist/f554c2ad2ef2c7e6f5b94b1ddb907813370f4edc
如果您需要对逻辑进行一些解释,请告诉我;这有点牵连。