ElasticSearch - 过滤嵌套聚合

9
我是一位有用的助手,可以为您翻译文本。以下是需要翻译的内容:

在过滤结果后进行聚合时,我遇到了问题。我认为我走在正确的道路上,但感觉自己像是在原地打转。

这是它的样子:

PUT /my_index
{
  "mappings": {
    "reporting": {
      "properties": {
        "events": {
          "type": "nested", 
          "properties": {
            "name":    { "type": "string", "index" : "not_analyzed"  },
            "date":    { "type": "date"    }
          }
        }
      }
    }
  }
}

因此,我的文档看起来像这样:

{
  "events": [
    { "name": "INSTALL", "date": "2014-11-01" },
    { "name": "UNINSTALL", "date": "2014-11-03" },
    { "name": "INSTALL", "date": "2014-11-04" },
    ...
  ]
}

现在,当我索引一些数据时,例如:
PUT /my_index/reporting/1
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-05"
    }
 ]
}

PUT /my_index/reporting/2
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-03"
    }
 ]
}

PUT /my_index/reporting/3
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-02"
    }
 ]
}

PUT /my_index/reporting/4
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-02"
    },
    {
       "name": "INSTALL",
       "date": "2014-11-03"
    }
 ]
}

PUT /my_index/reporting/5
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-03"
    },
    {
       "name": "INSTALL",
       "date": "2014-11-03"
    }
 ]
}

PUT /my_index/reporting/6
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-03"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-03"
    },
    {
       "name": "INSTALL",
       "date": "2014-11-05"
    }
 ]
}

PUT /my_index/reporting/7
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-02"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-03"
    },
    {
       "name": "INSTALL",
       "date": "2014-11-05"
    }
 ]
}

PUT /my_index/reporting/8
{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-01"
    }
 ]
}

我想要获取在2014-11-02(含当天)或之后安装但没有卸载(也就是卸载在2014-11-02之前或者没有卸载事件)的人数,并将其按照日期进行分组,用date_histogram表示(即将“日期”和“数量”数据放入桶中)。
我已经成功地对这个嵌套数据编写了过滤器,所以我能够获得筛选结果,但是当涉及到直方图聚合时,我仍然难以理解。
这就是我卡住的地方。
GET /my_index/reporting/_search
{
    "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "events",
                "filter": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "name": "INSTALL"
                        }
                      },
                      {
                        "range": {
                          "date": {
                            "gte": "2014-11-02"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "nested": {
                "path": "events",
                "filter": {
                  "bool": {
                    "should": [
                      {
                        "bool": {
                          "must_not": [
                            {
                              "term": {
                                "name": "UNINSTALL"
                              }
                            }
                          ]
                        }
                      },
                      {
                        "bool": {
                          "must": [
                            {
                              "term": {
                                "name": "UNINSTALL"
                              }
                            },
                            {
                              "range": {
                                "date": {
                                  "lt": "2014-11-02"
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  },
  "aggregations": {
    "filtered_result": {
      "filter": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "events",
                "filter": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "name": "INSTALL"
                        }
                      },
                      {
                        "range": {
                          "date": {
                            "gte": "2014-11-02"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "nested": {
                "path": "events",
                "filter": {
                  "bool": {
                    "should": [
                      {
                        "bool": {
                          "must_not": [
                            {
                              "term": {
                                "name": "UNINSTALL"
                              }
                            }
                          ]
                        }
                      },
                      {
                        "bool": {
                          "must": [
                            {
                              "term": {
                                "name": "UNINSTALL"
                              }
                            },
                            {
                              "range": {
                                "date": {
                                  "lt": "2014-11-02"
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      },
      "aggs": {
        "result": {
          "nested": {
            "path": "events"
          },
          "aggs": {
            "NAME": {
              "terms": {
                "field": "events.date",
                "format": "yyyy-MM-dd",
                "order": {
                  "_term": "asc"
                }
              }
            }
          }
        }
      }
    }
  }
}

我的结果看起来像:

... omitted 4 documents that match filter criteria ...
   "aggregations": {
      "filtered_result": {
         "doc_count": 4, <---- this is ok, I really have 4 docs that match criteria
         "result": {
            "doc_count": 12, <---- those 4 documents really have 12 events (together)
            "NAME": {
               "buckets": [
                  {
                     "key": 1414800000000,
                     "key_as_string": "2014-11-01",
                     "doc_count": 2
                  },
                  {
                     "key": 1414886400000,
                     "key_as_string": "2014-11-02",
                     "doc_count": 2
                  },
                  {
                     "key": 1414972800000,
                     "key_as_string": "2014-11-03",
                     "doc_count": 6
                  },
                  {
                     "key": 1415145600000,
                     "key_as_string": "2014-11-05",
                     "doc_count": 2
                  }
               ]
            }
         }
      }
   }

我希望获得类似如下内容:

"buckets": [
 {
   "key_as_string": "2014-11-02",
   "doc_count": 0
 },
 {
   "key_as_string": "2014-11-03",
   "doc_count": 2
 },
 {
   "key_as_string": "2014-11-04",
   "doc_count": 0
 },
 {
   "key_as_string": "2014-11-05",
   "doc_count": 2
 } 
]

基本上,符合条件的4个文档按照发生条件的日期分发,其中2个文档在“2011-11-03”发布,另外两个文档则在“2014-11-05”发布(这4个文档在2014-11-02之后有“安装”事件,并且没有卸载事件(它们仍然被安装)。

1个回答

1
这是部分答案。
主要问题在于,根据您的数据,实际上没有符合您要求的文档,因此我添加了一些文档:
curl -XPUT 'localhost:9200/my_index/reporting/9' -d '{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-03"
    }
 ]
}'

curl -XPUT 'localhost:9200/my_index/reporting/10' -d '{
  "events": [
    {
       "name": "INSTALL",
       "date": "2014-11-03"
    },
    {
       "name": "UNINSTALL",
       "date": "2014-11-01"
    }
  ]
}'

为了能够应用逻辑,我更改了架构,使得事件也包含在父级中——这样你就可以搜索“没有任何卸载事件”。因为问题在于,在嵌套搜索中,你总是只查看一个单一事件,所以你无法进行任何“全面报告”搜索。
curl -XPUT 'localhost:9200/my_index' -d '{
  "mappings": {
    "reporting": {
      "properties": {
        "events": {
          "type": "nested", "include_in_root": true,
          "properties": {
            "name":    { "type": "string", "index" : "not_analyzed"  },
            "date":    { "type": "date"    }
          }
        }
      }
    }
  }
}'

现在来谈谈查询本身。当使用嵌套过滤器时,似乎无法直接进入“过滤器”。您必须先执行“查询>过滤>过滤器”操作。

一般编写长的Elasticsearch查询的提示是记住除了“must”和“must_not”之外还有“and”和“or”运算符-就像编写代码一样。在您的情况下:

has_one(event.name == 'INSTALL' && event.date >= '2014-11-02')
&& has_none(event.name == 'UNINSTALL') 
&& has_none(event.name == 'UNINSTALL' && event.date >= '2014-11-02')

或者:

has_one(event.name == 'INSTALL' && event.date >= '2014-11-02')
&& ( has_none(event.name == 'UNINSTALL') 
     || has_only(event.name == 'UNINSTALL' && event.date >= '2014-11-02') )

我能够应用除了最后的 has_only / has_none 之外的所有内容。对于这个,你可能想尝试使用子文档。在那里,你至少可以在 must_not 布尔下使用 has_child 过滤器。
当前查询:
GET /my_index/reporting/_search
{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "and": {
          "filters": [
            {
              "or": {
                "filters": [
                  {
                    "bool": {
                      "must_not": [
                        {
                          "term": {
                            "events.name": "UNINSTALL"
                          }
                        }
                      ]
                    }
                  },
                  {
                    "nested": {
                      "path": "events",
                      "query": {
                        "filtered": {
                          "filter": {
                            "bool": {
                              "must": [
                                {
                                  "term": {
                                    "name": "UNINSTALL"
                                  }
                                },
                                {
                                  "range": {
                                    "date": {
                                      "lt": "2014-11-02"
                                    }
                                  }
                                }
                              ]
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              }
            },
            {
              "nested": {
                "path": "events",
                "query": {
                  "filtered": {
                    "filter": {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "name": "INSTALL"
                            }
                          },
                          {
                            "range": {
                              "date": {
                                "gte": "2014-11-02"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  },
  "aggregations": {
    "filtered_result": {
      "filter": {
        "and": {
          "filters": [
            {
              "or": {
                "filters": [
                  {
                    "bool": {
                      "must_not": [
                        {
                          "term": {
                            "events.name": "UNINSTALL"
                          }
                        }
                      ]
                    }
                  },
                  {
                    "nested": {
                      "path": "events",
                      "query": {
                        "filtered": {
                          "filter": {
                            "bool": {
                              "must": [
                                {
                                  "term": {
                                    "name": "UNINSTALL"
                                  }
                                },
                                {
                                  "range": {
                                    "date": {
                                      "lt": "2014-11-02"
                                    }
                                  }
                                }
                              ]
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              }
            },
            {
              "nested": {
                "path": "events",
                "query": {
                  "filtered": {
                    "filter": {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "name": "INSTALL"
                            }
                          },
                          {
                            "range": {
                              "date": {
                                "gte": "2014-11-02"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          ]
        }
      },
      "aggs": {
        "result": {
          "nested": {
            "path": "events"
          },
          "aggs": {
            "NAME": {
              "terms": {
                "field": "date",
                "format": "yyyy-MM-dd",
                "order": {
                  "_term": "asc"
                }
              }
            }
          }
        }
      }
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接