如何检查嵌套类型elasticsearch对象中的缺失键?

时间:2014-07-18 05:43:29

标签: json elasticsearch

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

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

这是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
            }
        ]
    }
}

这就是它的映射

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

规则标准

列出包含name AthenaOracle database的推文有opencursors less than recommendaed value 4000opencursors is not present时的推文的文档。

因此,仅当以下匹配时,上述文档/twitter/tweet/1才会返回。

  1. 如果(姓名=="雅典娜")&& (db。@ type包含" Oracle"关键字)
  2. 和(if((&#34; open_cursors&#34; @value&lt; 4000)或(&#34; open_cursors&#34;未在&#34下找到; db.oracle_props。@ name&#34;)< / LI>

    下面是与上述文档匹配的搜索查询,但缺少最后一个条件(显示文档&#34; / twitter / tweet / 1&#34;即使&#34; open_cursors&#34;密钥丢失在&#34; db.oracle_props。@ name&#34;)

    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
          }
       }
    }
    

1 个答案:

答案 0 :(得分:3)

我会再试一次,引用你的other questionmy answer

如果我理解您的要求,我会设置一些示例文档,这些文档应该或不应该与我的评论正确匹配:

// 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"
            }
        ]
    }
}'

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

我发现的解决方案似乎相当复杂,也许其他人可以提供更简单的方法来解决这个问题?

我已设置filtered query,以便能够使用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"}
                        }
                    ]
                }
            }
        }
    }
}
'

返回文件1,2和3。

更新: 这是一个更简单的解决方案,也应该有效。谢谢@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"}
                        }
                    ]
                }
            }
        }
    }
}
'