如何检查嵌套类型弹性搜索对象中缺少的键? [英] How to check missing key in a nested type elasticsearch object?

查看:86
本文介绍了如何检查嵌套类型弹性搜索对象中缺少的键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个案例,我收集一些一般信息& db信息(db2,oracle,sybase,informix)在键值对json格式doc。



我还有一些规则来检查上述文件是否满足特定规则,如果满意地将该特定文档作为分析结果返回。



这里是文档

  PUT / twitter / tweet / 1 
{
name:Athena,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4。 0 64bit,
oracle_props:[
{
@name:open_cursors,
@value:4000
},
{
@name:USER_ROLE_PRIVS_COUNT,
@value:1
}
]
}
}

这是它的映射

  PUT / twitter / tweet / _mapping 
{
properties:{
db:{
type:object,
属性:{
@type:{
type:string
},
oracle_props:{
type:nested,
properties:{
@name :{
type:string
},
@value:{
type:long
}
}
}
}
}
}
}

规则条件



列出文档与名称的推文雅典娜 Oracle数据库具有 opencursors小于推荐值4000 opencursors不存在



所以上面的文档 / twitter / tweet / 1 应该回到只有在以下情况下才会结果。


  1. 如果(name ==Athena)&& (db。@ type包含Oracle关键字)

  2. 和(如果((open_cursors@value< 4000)或(open_cursors在db.oracle_props。名称)

以下是与doc相匹配的搜索查询,但缺少最后一个条件(显示文档/ twitter / tweet / 1即使在db.oracle_props。@ name下缺少open_cursors键)

  GET / twitter / tweet / _search 
{
查询:{
bool:{
必须:[
{
匹配:{
tweet.name:雅典娜
}
},
{
匹配:{
tweet.db 。@ type:Oracle
}
}
],
应该:[
{
嵌套:{
path:db.oracle_props,
query:{
boo l:{
must:[
{
term:{
db.oracle_props。@ name:open_cursors
}
$,
{
范围:{
db.oracle_props。@ value:{
lt:4001
}
}
}
]
}
}
}
}
],
minimum_should_match:1

}
}


解决方案

我再来一次,参考你的其他问题



我'我会设置一些示例文档,如果我理解你的要求,应该或不应该正确地匹配我的意见:

  / /所有好,应该匹配
curl -XPUT'http:// localhost:9200 / twitter / tweet / 1'-d'{
name:Athena,
version :1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props:[
{
@name:open_cursors,
@value:4000
},
{
@name:USER_ROLE_PRIVS_COUNT,
@value:1
},
{
@name:CREATE _PERMISSION,
@value:Y
}
]
}
}'

//打开游标,应该匹配
curl -XPUT'http:// localhost:9200 / twitter / tweet / 2'-d'{
name:Athena,
version
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props:[
{
@name:USER_ROLE_PRIVS_COUNT,
@value:2
},
{
@name:CREATE_PERMISSION,
@值:N
}
]
}
}'

// open_cursors小于4000,应该匹配
curl - XPUT'http:// localhost:9200 / twitter / tweet / 3'-d'{
name:Athena,
version:1,
db {
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_prop s:[
{
@name:open_cursors,
@value:2134
},
{
@name :USER_ROLE_PRIVS_COUNT,
@value:6
},
{
@name:CREATE_PERMISSION,
@value N
}
]
}
}'

//不同的名字,不应该匹配
curl -XPUT'http: // localhost:9200 / twitter / tweet / 4'-d'{
name:Alexandroupolis,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props:[
{
@name:open_cursors,
@value:4000
},
{
@name:USER_ROLE_PRIVS_COUNT,
@value:1
},
{
@name:CREATE_PERMISSION,
@value:Y
}
]
}
}'

// open_cursors超过4000,不应该匹配
curl -XPUT'http:// localhost:9200 / twitter / tweet / 5'-d'{
name:Athena,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props [
{
@name:open_cursors,
@value:6500
},
{
@name USER_ROLE_PRIVS_COUNT,
@value:1
},
{
@name:CREATE_PERMISSION,
@value:Y
}
]
}
}'

因此我们有3个文件( ID 1,2,3 ),应该返回。



我发现似乎很复杂,也许别人可以提供一个更简单的方法来解决这个问题?



我已经设置了一个过滤查询,以便能够使用 OR 过滤器

  curl -XGET'http:// localhost:9200 / twitter / tweet / _search ?nice = true'-d'
{
query:{
filtered:{
filter:{
/ *设置两个条件* /
或:[
/ * First * /
{
/ *检查open_cursors AND值< 4000 * /
bool:{
must:[
/ *与其他问题一样的嵌套查询回答* /
{
嵌套 {
path:db.oracle_props,
filter:{
bool:{
must:[
{
term:{
db.oracle_props。@ name:open_cursors
}
},
{
range:{
db.oracle_props。@ value:{
lte:4000
}
}
}
]
}
}
}
}
]
}
},
/ * OR * /
{
bool:{
/ *注意:否定,这不能被发现* /
must_not:[
{
嵌套:{
path:db.oracle_props,
filter:{
bool:{
/ *我们不希望open_cursors在嵌套文档中* /
必须:[
{
term:{
db.oracle_props。@ name:open_cursors
}
}
]
}
}
}
}
]

}
]
},
/ *非嵌套事物的查询* /
查询:{
bool: {
must:[
{
match:{tweet.name:Athena}
},
{
匹配:{tweet.db。@ type:Oracle}
}
]
}
}
}
}
}
'

返回文件1,2和3。



更新:
这是一个更简单的解决方案,也应该工作。感谢@TuanHuynh

  curl -XGET'http:// localhost:9200 / twitter / tweet / _search?pretty = true' d'
{
查询:{
过滤:{
过滤器:{
/ *设置两个条件* /
或:[
/ * First * /
{
嵌套:{
path:db.oracle_props,
filter {
bool:{
must:[
{
term:{
db.oracle_props。@ name:open_cursors
}
},
{
范围:{
db.oracle_props。@ value:{
lte:4000
}
}
}
]
}
}
}
},
/ * OR * /
{
嵌套:{
path:db.oracle_props,
filter:{
bool:{
/ *我们不希望open_cursors在嵌套文档中* /
必须:[
{
term:{
db.oracle_props。@ name:open_cursors
}
}
]
}
}
}
}

},
/ *查询非嵌套事物* /
查询:{
bool:{
必须: [
{
match:{tweet.name:Athena}
},
{
match:{tweet.db。 @type:Oracle}
}
]
}
}
}
}
}
'


I have a case where I collect some general info & db information (db2, oracle, sybase, informix) in key value pairs json format doc.

I also have some rules to check whether the above doc satisfies a particular rule, if satisfied give back that particular doc for analysis as a result.

here is the doc

PUT /twitter/tweet/1
{
    "name": "Athena",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "open_cursors",
                "@value": 4000
            },
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 1
            }
        ]
    }
}

and this is it's mapping

PUT /twitter/tweet/_mapping
{
   "properties": {
      "db": {
         "type": "object",
         "properties": {
            "@type": {
               "type": "string"
            },
            "oracle_props": {
               "type": "nested",
               "properties": {
                  "@name": {
                     "type": "string"
                  },
                  "@value": {
                     "type": "long"
                  }
               }
            }
         }
      }
   }
}

Rule criteria

List out docs where tweet with name Athena and a Oracle database has opencursors less than recommendaed value 4000 or when opencursors is not present.

So the above doc /twitter/tweet/1 should come back as a result only if the following matches.

  1. If (name == "Athena") && (db.@type contains "Oracle" keyword)
  2. and (if (("open_cursors" @value < 4000) or ("open_cursors" not found under "db.oracle_props.@name")

below is the search query which matches above doc but is missing the last condition (display doc "/twitter/tweet/1" even when "open_cursors" key is missing under "db.oracle_props.@name")

GET /twitter/tweet/_search
{
   "query": {
      "bool": {
         "must": [
            {
               "match": {
                  "tweet.name": "Athena"
               }
            },
            {
               "match": {
                  "tweet.db.@type": "Oracle"
               }
            }
         ],
         "should": [
            {
               "nested": {
                  "path": "db.oracle_props",
                  "query": {
                     "bool": {
                        "must": [
                           {
                              "term": {
                                 "db.oracle_props.@name": "open_cursors"
                              }
                           },
                           {
                              "range": {
                                 "db.oracle_props.@value": {
                                    "lt": 4001
                                 }
                              }
                           }
                        ]
                     }
                  }
               }
            }
         ],
         "minimum_should_match": 1
      }
   }
}

解决方案

I'll give it another go, referencing your other question and my answer.

I'll set up some example documents, that should or should not match correctly regarding my comments, if I understood your demands right:

// All good, should match
curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
    "name": "Athena",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "open_cursors",
                "@value": 4000
            },
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 1
            },
            {
                "@name": "CREATE_PERMISSION",
                "@value": "Y"
            }
        ]
    }
}'

// open cursors missing, should match
curl -XPUT 'http://localhost:9200/twitter/tweet/2' -d '{
    "name": "Athena",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 2
            },
            {
                "@name": "CREATE_PERMISSION",
                "@value": "N"
            }
        ]
    }
}'

// open_cursors less than 4000, should match
curl -XPUT 'http://localhost:9200/twitter/tweet/3' -d '{
    "name": "Athena",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "open_cursors",
                "@value": 2134
            },
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 6
            },
            {
                "@name": "CREATE_PERMISSION",
                "@value": "N"
            }
        ]
    }
}'

// Different name, shouldn't match
curl -XPUT 'http://localhost:9200/twitter/tweet/4' -d '{
    "name": "Alexandroupolis",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "open_cursors",
                "@value": 4000
            },
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 1
            },
            {
                "@name": "CREATE_PERMISSION",
                "@value": "Y"
            }
        ]
    }
}'

// open_cursors more than 4000, shouldn't match
curl -XPUT 'http://localhost:9200/twitter/tweet/5' -d '{
    "name": "Athena",
    "version": 1,
    "db": {
        "@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
        "oracle_props": [
            {
                "@name": "open_cursors",
                "@value": 6500
            },
            {
                "@name": "USER_ROLE_PRIVS_COUNT",
                "@value": 1
            },
            {
                "@name": "CREATE_PERMISSION",
                "@value": "Y"
            }
        ]
    }
}'

Hence we've got 3 documents (ID 1,2,3) that should be returned.

The solution that I've found seems quite complicated, maybe someone else can provide an easier way to solve this?

I've set up a filtered query, in order to be able to use an OR filter

curl -XGET 'http://localhost:9200/twitter/tweet/_search?pretty=true' -d '
{
    "query" : {
        "filtered" : {
            "filter" : {
                /* Set up two conditions */
                "or" : [
                    /* First */
                    {
                        /* Check for open_cursors AND value < 4000 */
                        "bool" : {
                            "must" : [
                                /* Same nested query as in other questions answer */
                                {
                                    "nested" : {
                                        "path" : "db.oracle_props",
                                        "filter" : {
                                            "bool" : {
                                                "must" : [
                                                    {
                                                    "term": {
                                                        "db.oracle_props.@name": "open_cursors"
                                                    }
                                                },
                                                {
                                                    "range": {
                                                        "db.oracle_props.@value": {
                                                            "lte": 4000
                                                        }
                                                    }
                                                }
                                                ]
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    /* OR */
                    {
                        "bool" : {
                            /* watch out: negation, this MUST NOT be found*/
                            "must_not" : [
                                {
                                    "nested" : {
                                        "path" : "db.oracle_props",
                                        "filter" : {
                                            "bool" : {
                                                /* We do not want open_cursors to be in the nested document */
                                                "must" : [
                                                    {
                                                    "term": {
                                                        "db.oracle_props.@name": "open_cursors"
                                                    }
                                                }
                                                ]
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    }
                ]
            },
            /* the query for the non-nested things */
            "query" : {
                "bool" : {
                    "must" : [
                        {
                            "match" : {"tweet.name" : "Athena"}
                        },
                        {
                            "match" : {"tweet.db.@type" : "Oracle"}
                        }
                    ]
                }
            }
        }
    }
}
'

Return documents 1,2 and 3.

Update: This is a simpler solution and should work, too. Thanks @TuanHuynh

curl -XGET 'http://localhost:9200/twitter/tweet/_search?pretty=true' -d '
{
    "query" : {
        "filtered" : {
            "filter" : {
                /* Set up two conditions */
                "or" : [
                    /* First */
                    {
                        "nested" : {
                            "path" : "db.oracle_props",
                            "filter" : {
                                "bool" : {
                                    "must" : [
                                        {
                                        "term": {
                                            "db.oracle_props.@name": "open_cursors"
                                        }
                                    },
                                    {
                                        "range": {
                                            "db.oracle_props.@value": {
                                                "lte": 4000
                                            }
                                        }
                                    }
                                    ]
                                }
                            }
                        }
                    },
                    /* OR */
                    {
                        "nested" : {
                            "path" : "db.oracle_props",
                            "filter" : {
                                "bool" : {
                                    /* We do not want open_cursors to be in the nested document */
                                    "must" : [
                                        {
                                        "term": {
                                            "db.oracle_props.@name": "open_cursors"
                                        }
                                    }
                                    ]
                                }
                            }
                        }
                    }
                ]
            },
            /* the query for the non-nested things */
            "query" : {
                "bool" : {
                    "must" : [
                        {
                            "match" : {"tweet.name" : "Athena"}
                        },
                        {
                            "match" : {"tweet.db.@type" : "Oracle"}
                        }
                    ]
                }
            }
        }
    }
}
'

这篇关于如何检查嵌套类型弹性搜索对象中缺少的键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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