filter - ElasticSearch - 过滤嵌套聚合

标签 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 含义(具有“日期”->“计数”数据的桶)。

我设法在这个嵌套数据上编写了过滤器,所以我可以获得过滤后的结果,但是当涉及到直方图聚合时,我一直在追赶我的尾部。

这就是我卡住的地方。

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 个文档在之后有事件“install” 2014-11-02 之后没有卸载事件(它们仍然安装)。

最佳答案

这是部分答案。

有一个主要问题:根据您的资料,实际上没有符合您要求的文档,所以我添加了一些:

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

关于filter - ElasticSearch - 过滤嵌套聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26732254/

相关文章:

c# - 索引格式每天更改为每周

java - 实现声明嵌套接口(interface)的父接口(interface)时会发生什么

javascript - 嵌套 Node async.eachSeries

android - ListView 过滤器计数

c++ - 如何在 C++ 中过滤字符串 vector ?

notepad++ - Notepad++文件过滤器

sorting - Elasticsearch:按计算出的日期值排序

json - 在负载中指定 elasticsearch 索引

swift - 如何防止 Swift 3 中的嵌套完成 block ?

javascript - selectAll() 之后的 D3 filter()