Elasticsearch-过滤哪里(嵌套数组之一)和(所有嵌套数组) [英] Elasticsearch - Filter where (one of nested array) and (all of nested array)

查看:266
本文介绍了Elasticsearch-过滤哪里(嵌套数组之一)和(所有嵌套数组)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR -如何检查一个所有嵌套数组是否满足指定条件?

TL;DR - How do I check whether one-of and all-of a nested array meet specified criteria?

我有一个document.每个document都有一个嵌套的outer对象的数组,这些对象本身也具有一个嵌套的inner对象的列表.我需要对至少一个文档的嵌套对象匹配的所有文档执行过滤器.当我说匹配时,我的意思是全部 outer嵌套对象的inner对象以某种方式匹配.这是一个示例映射,以供参考;

I have a document. Each document has an array of nested outer objects, who themselves have a list of nested inner objects. I need to perform a filter for all documents where at least one of the document's outer nested objects match. When I say match, I mean that all the outer nested objects' inner objects match in some way. Here's an example mapping for reference;

{ "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",则如果match是指定的国家代码,例如ES,则inner对象将被视为匹配.一个文档中的inner对象可能具有不同的type对象,并且不能保证存在特定的类型.

If the document has no outer/inner objects it is considered to match. But to make things worse the inner objects need to be considered to match differently depending on the type in a kind of conditional logic manner (eg CASE in SQL). For example, if the type were the term "Country" then inner object would be considered to match if the match were a specified country code such as ES. A document may have inner objects of varying type and there is not guarantee that specific types will exist.

来自命令式(Java)编程背景,我在解决如何实现这种过滤方面遇到了难以置信的麻烦.我什至无法想像这种行为.到目前为止,我所拥有的只是经过过滤的查询;

Coming from a imperative (Java) programming background I am having incredible trouble figuring out how to implement this kind of filtering. Nothing I can think of even vaguely matches this behaviour. Thus far all I have is the filtered query;

"filtered" : {
      "query" : {
        "match_all" : { }
      },
      "filter" : {
        "bool" : {
          "should" : {
            "missing" : {
              "field" : "outer.inner.type"
            }
    }}}}
}

所以,问题是...

如何过滤具有至少一个 outer对象且根据innertype匹配全部 inner个对象的文档对象?

How can I filter to documents who have at least one outer object which has all inner objects matching based on the type of inner object?

根据请求的其他详细信息-

Further details By Request -

{
    "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对象都不会麻烦其inner对象完全匹配.如果我们希望第二个outer对象匹配,那么所有三个inner都需要匹配.请注意,第三个inner中还有一个额外的type.这会导致以下情况:如果类型存在然后,则该类型需要与其匹配否则,因为它不需要匹配缺席.

The above example should come through the filter if we were to provide "1st Class" market and the country "GRB" because the second of the two outer objects would be considered a match because both inner objects match. If, however, we provided the country country "GRB" and the market "Elite" then we would not have this document returned because neither of the outer objects would have bother of their inner objects match in their entirety. If we wanted the second outer object to match then all three inner would need to match. Take note that there is an extra type in the third inner. This leads to a situation where if a type exists then it needs to have a match for it else it doesn't need to match because it is absent.

推荐答案

嵌套数组之一

具有其中一个符合某些条件的嵌套数组非常简单. 嵌套过滤器的值等于/true嵌套对象数组中的匹配指定的内部过滤器.例如,给定一个outer个对象的数组,其中那些对象之一具有值为"matching"的字段match,则以下条件为真.

One of Nested Array

Having one of a nested array matching some criteria turns out to be very simple. A nested filter evaluates to matching/true if any of the array of nested objects match the specified inner filters. For example, given an array of outer objects where one of those objects has a field match with the value "matching" the following would be considered true.

"nested": {
   "path": "outer",
   "filter": {
       "term" : { "match" : "matching" } 
   }
}

如果其中一个嵌套的outer对象具有名为match且值为"matching"的字段,则上述内容将为true/matching.

The above will be considered true/matching if one of the nested outer objects has a field called match with the value "matching".

只有在数组匹配中的所有所有嵌套对象更有趣时,才认为具有嵌套过滤器是匹配的.实际上,这是不可能的.但是,如果只有一个嵌套对象与过滤器匹配就被认为是匹配的,我们可以颠倒逻辑并说如果的嵌套对象不匹配"实现我们所需要的.例如,给定一个嵌套的outer.inner对象数组,其中所有这些对象都有一个值为"matching"的字段match,则以下条件为真.

Having a nested filter only be considered matching if all of the nested objects in an array match is more interesting. In fact, it's impossible. But given that it is considered matching if only one of the nested objects match a filter we can reverse the logic and say "If none of the nested objects don't match" to achieve what we need. For example, given an array of nested outer.inner objects where all of those objects has a field match with the value "matching" the following would be considered true.

"not" : {
   "nested": {
      "path": "outer.inner",
      "filter": {
          "not" : {
              "term" : { "match" : "matching" } 
          }
      }
   }
}

以上内容将被认为是正确的/匹配的,因为没有的嵌套outer.inner对象(双重否定)具有名为match的值"matching".当然,这与所有嵌套的inner对象相同,这些对象的字段match的值为"matching".

The above will be considered true/matching because none of the nested outer.inner objects don't (double negative) have a field called match with the value "matching". This, of course, is the same as all of the nested inner objects having a field match with the value "matching".

使用传统的缺少过滤器始终被认为是正确的.但是,您可以做的是检查match_all过滤器是否不返回任何结果;

You can't check whether a field containing nested objects is missing using the traditional missing filter. This is because nested objects aren't actually in the document at all, they are stored somewhere else. As such missing filters will always be considered true. What you can do however, is check that a match_all filter returns no results like so;

"not": {
   "nested": {
      "path": "outer",
      "filter": {
          "match_all": {}
       }
    }
 }

如果match_all未找到结果,则认为这是正确的/匹配的.

This is considered true/matching if match_all finds no results.

这篇关于Elasticsearch-过滤哪里(嵌套数组之一)和(所有嵌套数组)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆