如何通过键值对弹性搜索数组中的键来匹配数组值?

时间:2014-07-11 04:47:16

标签: json elasticsearch

我有一对key value对。是否可以精确匹配key&的匹配值然后检查它的value的范围值?

示例:在下面的文档中,oracle_props是一个包含名称,值对的数组。我需要检查它是否有"oracle_cursors"密钥,然后检查它的值是否小于1000.

GET /eg/message/_percolate
{
   "doc": {
      "client": {
         "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"
               }
            ]
         }
      }
   }
}

以下是我的过滤器。

我还需要检查以下内容,以便它返回3作为我的结果

  1. “client.name”必须是“Athena”
  2. “client.db。@ type”必须是“Oracle”,然后才能继续检查以下几点
  3. 找不到“client.db.oracle_props。@ name”字段
  4. 检查它是否有“oracle_cursors”键,然后检查它的值是否为< 1000
  5. 1& 2是和操作,3或4中的任何一个满足它应该得到3。我需要第4点的帮助,下面是我的查询。如果有更好的方法,请建议。

    PUT /eg/.percolator/3
    {
       "query": {
          "filtered": {
             "filter": {
                "or": [
                   {
                      "missing": {
                         "field": "client.db.oracle_props.@name"
                      }
                   }
                ]
             },
             "query": {
                "bool": {
                   "must": [
                      {
                         "match": {
                            "client.name": "Athena"
                         }
                      },
                      {
                         "match": {
                            "client.db.@type": "Oracle"
                         }
                      }
                   ]
                }
             }
          }
       }
    }
    

    更新

    我可以使用下面的内容

    {
         "match": {
                        "client.db.oracle_props[name='open_cursors'].value": 4000
                     }
                  }
    

    尝试更多

    我关注elasticsearch nested query并通过重新编制索引将映射更改为nestedtype。任何人都可以找到问题为什么我得到nested: NullPointerException;

    PUT /eg/.percolator/3
    {
       "nested" : {
            "path" : "client.db.oracle_props",
            "score_mode" : "avg",
            "query" : {
                "bool" : {
                    "must" : [
                        {
                            "match" : {"client.db.oracle_props.@name" : "open_cursors"}
                        },
                        {
                            "range" : {"client.db.oracle_props.@value" : {"lt" : 4000}}
                        }
                    ]
                }
            }
        }
    }
    

    映射更改

    ...
    "properties": {
                   "@type": {
                      "type": "string"
                   },
                   "oracle_props": {
                       "type" : "nested",
                      "properties": {
                         "@name": {
                            "type": "string"
                         },
                         "@value": {
                            "type": "long"
                         }
                      }
                   }
                }
    ...
    

2 个答案:

答案 0 :(得分:5)

让我们进入它:

  1. 您似乎将嵌套路径映射错误,oracle_props是示例文档中db的子项,但不在您的映射中,它直接显示为您的根的子项。
  2. 您将oracle_props.@value映射为long,但在Y嵌套文档
  3. 上为其指定了文字CREATE_PERMISSION
  4. 您查询range lt 4000排除 4000,lte适合您
  5. 我没有得到你对缺失值的要求,因此我跳过了。

    为了让你走上正确的道路,我必须稍微简化一下(因为我无法解决你问题中的所有混乱,抱歉)

    我也没有进入渗透,并将所有内容重命名为推特/推特,因为我更容易从我的示例中复制。

    1)创建空索引" twitter"

    curl -XDELETE 'http://localhost:9200/twitter/'
    curl -XPUT 'http://localhost:9200/twitter/'
    

    2)为实际"推文"

    创建geo_point映射
    curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d '
    {
        "tweet": {
            "properties": {
                "db": {
                    "type": "object",
                    "properties": {
                        "@type": {
                            "type": "string"
                        },
                        "oracle_props": {
                            "type": "nested",
                            "properties": {
                                "@name": {
                                    "type": "string"
                                },
                                "@value": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    }'
    

    3)让我们检查映射是否已设置

    curl -XGET 'http://localhost:9200/twitter/tweet/_mapping?pretty=true'
    

    4)发布一些推文,包含嵌套数据

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

    5)仅嵌套查询

    curl -XGET localhost:9200/twitter/tweet/_search -d '{
        "query": {
            "nested" : {
                "path" : "db.oracle_props",
                "score_mode" : "avg",
                "query" : {
                    "bool" : {
                        "must" : [
                            {
                                "term": {
                                    "db.oracle_props.@name": "open_cursors"
                                }
                            },
                            {
                                "range": {
                                    "db.oracle_props.@value": {
                                        "lte": 4000
                                    }
                                }
                            }
                        ]
                    }
                }
            }
        }
    }';
    

    6)查询" Athena"和#34; Oracle"

    curl -XGET localhost:9200/twitter/tweet/_search -d '{
        "query" : {
            "bool" : {
                "must" : [
                    {
                        "match" : {"tweet.name" : "Athena"}
                    },
                    {
                        "match" : {"tweet.db.@type" : "Oracle"}
                    }
                ]
            }
        }
    }'
    

    7)结合前两个查询

    curl -XGET localhost:9200/twitter/tweet/_search -d '{
        "query" : {
            "bool" : {
                "must" : [
                    {
                        "match" : {"tweet.name" : "Athena"}
                    },
                    {
                        "match" : {"tweet.db.@type" : "Oracle"}
                    },
                    {
                        "nested" : {
                            "path" : "db.oracle_props",
                            "score_mode" : "avg",
                            "query" : {
                                "bool" : {
                                    "must" : [
                                        {
                                            "term": {
                                                "db.oracle_props.@name": "open_cursors"
                                            }
                                        },
                                        {
                                            "range": {
                                                "db.oracle_props.@value": {
                                                    "lte": 4000
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }'
    

    结果

    {
        "took": 2,
        "timed_out": false,
        "_shards": {
            "total": 5,
            "successful": 5,
            "failed": 0
        },
        "hits": {
            "total": 1,
            "max_score": 2.462332,
            "hits": [
                {
                    "_index": "twitter",
                    "_type": "tweet",
                    "_id": "1",
                    "_score": 2.462332,
                    "_source": {
                        "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"
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
    

答案 1 :(得分:0)