json - 如何通过键值对elasticsearch数组中的键来匹配数组值?

标签 json elasticsearch

我有一组键值对。是否可以精确匹配 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

1 和 2 是 and 操作,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"
                     }
                  }
               }
            }
...

最佳答案

让我们开始吧:

  1. 您似乎将嵌套路径映射错误,oracle_props 在您的示例文档中是 db 的子项,但在您的映射中不是,它直接显示为子项你的根。
  2. 您正在将 oracle_props.@value 映射为 long,但在 CREATE_PERMISSION 中为其分配文本 Y > 嵌套文档
  3. 您查询 range lt 4000不包括 4000,lte 适合您

我没有得到您对缺失值的要求,因此我跳过了它。

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

我也不打算渗透,而是将所有内容重命名为 twitter/tweet,因为这对我来说更容易从我的示例中复制。

1) 创建空索引“twitter”

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

2) 为实际的“tweet”创建 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”和“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"
                            }
                        ]
                    }
                }
            }
        ]
    }
}

关于json - 如何通过键值对elasticsearch数组中的键来匹配数组值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24690293/

相关文章:

java - 如何添加com.google.gson.JsonArray 的特定索引?

php - Android 将 JSON 发布到 Web 服务 php 并从服务接收 JSON

c# - Json.NET 序列化中有没有办法区分 "null because not present"和 "null because null"?

javascript - 将 PHP 数组传递给 js 变量

regex - 如何在正则表达式中获取多个值?

elasticsearch - Elasticsearch父子关系缩放

java - 如何将 POJO 映射到多个 JSON 表示

java - 通过使用条件语句和 Java Api 构建 ElasticSearch BoolQuery

elasticsearch - 在Elasticsearch中创建时设置ID

elasticsearch - 过滤掉元数据字段,只返回elasticsearch中的源字段