弹性中的嵌套布尔聚合

Nested boolean aggregation in elastic

我有 json 个有效载荷

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 61,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "myindex",
        "_type" : "_doc",
        "_id" : "CAojVWwBO8H0jj7a_j3P",
        "_score" : 1.0,
        "_source" : {
          "appName" : "BigApp",
          "appVer" : "1.0",
          "reviews" : {
            "reviewer" : {
              "value" : "Bob"
            },
            "testsPass" : [
              {
                "name" : "unit",
                "pass" : false
              },
              {
                "name" : "integraton",
                "pass" : false
              },
              {
                "name" : "ui",
                "pass" : false
              }
            ]
          }
        }
      }
    ]
  }
}

在弹性中,如果所有 pass 值都是 .

我是 Elastic 的新手,正在努力编写那种形式的查询,有人可以帮忙吗?

到目前为止,我已经尝试了 nested aggregators,但语法不正确。

查看您的数据,我假设您的映射结构如下:

映射:

PUT myindex
{
  "mappings": {
    "properties": {
      "appName":{
        "type": "keyword"
      },
      "appVer": {
        "type": "keyword"
      },
      "reviews":{
        "properties": {
          "reviewer":{
            "properties":{
              "value": {
                "type": "keyword"
              }
            }
          },
          "testsPass":{
            "type": "nested"
          }
        }
      }
    }
  }
}

示例文档:

POST myindex/_doc/1
{  
   "appName":"BigApp",
   "appVer":"1.0",
   "reviews":{  
      "reviewer":{  
         "value":"Bob"
      },
      "testsPass":[  
         {  
            "name":"unit",
            "pass":false
         },
         {  
            "name":"integraton",
            "pass":false
         },
         {  
            "name":"ui",
            "pass":false
         }
      ]
   }
}

POST myindex/_doc/2
{  
   "appName":"MidApp",
   "appVer":"1.0",
   "reviews":{  
      "reviewer":{  
         "value":"Bob"
      },
      "testsPass":[  
         {  
            "name":"unit",
            "pass":true
         },
         {  
            "name":"integraton",
            "pass":true
         },
         {  
            "name":"ui",
            "pass":true
         }
      ]
   }
}

POST myindex/_doc/3
{  
   "appName":"SmallApp",
   "appVer":"1.0",
   "reviews":{  
      "reviewer":{  
         "value":"Bob"
      },
      "testsPass":[  
         {  
            "name":"unit",
            "pass":true
         },
         {  
            "name":"integraton",
            "pass":true
         },
         {  
            "name":"ui",
            "pass":false
         }
      ]
   }
}

请注意,在上述文档列表中,只有具有appName: MidApp(第2个文档)的文档具有所有true值的列表。

聚合查询:

POST myindex/_search
{  
   "size":0,
   "aggs":{  
      "pass_reviewers":{  
         "filter":{  
            "bool":{  
               "must":[  
                  {  
                     "nested":{  
                        "path":"reviews.testsPass",
                        "query":{  
                           "match":{  
                              "reviews.testsPass.pass":"true"
                           }
                        }
                     }
                  }
               ],
               "must_not":[  
                  {  
                     "nested":{  
                        "path":"reviews.testsPass",
                        "query":{  
                           "match":{  
                              "reviews.testsPass.pass":"false"
                           }
                        }
                     }
                  }
               ]
            }
         },
         "aggs":{  
            "myhits":{  
               "top_hits":{  
                  "size":10
               }
            }
         }
      }
   }
}

注意以上return只是Top Hits aggregation. The main aggregation over here is in filter section which is just a Filter Aggregation

的相关文件

回复:

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "pass_reviewers" : {
      "doc_count" : 1,             <------ Note this. Returns count of docs. This is result of filtered aggregation
      "myhits" : {                 <------ Start of top hits aggregation
        "hits" : {
          "total" : {
            "value" : 1,                    
            "relation" : "eq"
          },
          "max_score" : 1.0,
          "hits" : [
            {
              "_index" : "myindex",
              "_type" : "_doc",
              "_id" : "2",                 <----- Document 
              "_score" : 1.0,
              "_source" : {
                "appName" : "MidApp",
                "appVer" : "1.0",
                "reviews" : {
                  "reviewer" : {
                    "value" : "Bob"
                  },
                  "testsPass" : [
                    {
                      "name" : "unit",
                      "pass" : true
                    },
                    {
                      "name" : "integraton",
                      "pass" : true
                    },
                    {
                      "name" : "ui",
                      "pass" : true
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    }
  }
}

以防万一,如果您只想查询 return 所有 true 的文档,而不一定要使用聚合,您可以简单地使用以下查询:

查询:

POST myindex/_search
{  
   "query":{  
      "bool":{  
         "must":[  
            {  
               "nested":{  
                  "path":"reviews.testsPass",
                  "query":{  
                     "match":{  
                        "reviews.testsPass.pass":"true"
                     }
                  }
               }
            }
         ],
         "must_not":[  
            {  
               "nested":{  
                  "path":"reviews.testsPass",
                  "query":{  
                     "match":{  
                        "reviews.testsPass.pass":"false"
                     }
                  }
               }
            }
         ]
      }
   }
}

基本上,核心执行逻辑在两个查询中是相同的,我只是缩小了您正在寻找的逻辑范围。

回复:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.597837,
    "hits" : [
      {
        "_index" : "myindex",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.597837,
        "_source" : {
          "appName" : "MidApp",
          "appVer" : "1.0",
          "reviews" : {
            "reviewer" : {
              "value" : "Bob"
            },
            "testsPass" : [
              {
                "name" : "unit",
                "pass" : true
              },
              {
                "name" : "integraton",
                "pass" : true
              },
              {
                "name" : "ui",
                "pass" : true
              }
            ]
          }
        }
      }
    ]
  }
}

希望对您有所帮助!