ElasticSearch - 过滤嵌套聚合

时间:2014-11-04 09:58:56

标签: filter elasticsearch nested aggregation

我在过滤后汇总结果时遇到问题。我想我走在正确的轨道上,但我觉得我在追逐自己的尾巴。

以下是它的外观:

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之后安装并且没有卸载的人数(因此,UNINSTALL是在2014-11-02之前或者没有UNINSTALL事件),并将他们分组date_histogram含义(要使用“date” - >“count”数据)。

我设法在这个嵌套数据上编写过滤器,所以我可以得到那个过滤结果,但是在直方图聚合方面我一直在追逐我的尾巴。

这就是我陷入困境的地方。

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个文件按发生标准的日期分发,“2011-11-03”上有2个文档,“2014-11-05”上有2个文档(4个文档后面有“安装”事件2014-11-02并且之后没有卸载事件(它们仍然安装)。

1 个答案:

答案 0 :(得分: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"
    }
  ]
}'

为了能够应用逻辑,我更改了Schema,以便事件也包含在父级中 - 这样您就可以搜索“没有任何UNINSTALL事件”。因为事情是,在嵌套搜索中,您总是只看一个单一事件,因此您无法进行任何类型的“报告范围”搜索。

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

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

总体上编写长弹性搜索查询的一个提示 - 记住除了“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 bool下使用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"
                }
              }
            }
          }
        }
      }
    }
  }
}