在将数据转换为直方图之前,如何重新整形数据?

Jim*_* G. 7 c# elasticsearch nest

想象一下,我有一个访问索引,其中包含类型为"visit"的文档,如下所示:

{
               "id": "c223a991-b4e7-4333-ba45-a576010b568b",
// other properties
               "buildingId": "48da1a81-fa73-4d4f-aa22-a5750162ed1e",
               "arrivalDateTimeUtc": "2015-12-22T21:15:00Z"
}
Run Code Online (Sandbox Code Playgroud)

以下函数将返回一个直方图,该直方图根据给定的时区返回给定范围内每一天的访问量.

    public Bucket<HistogramItem> Execute(MyParameterType parameters)
    {
        var buildingFilter = Filter<VisitProjection>.Term(x => x.BuildingId, parameters.BuildingId);
        var dateFilter = Filter<VisitProjection>.Range(r => r
            .OnField(p => p.ArrivalDateTimeUtc)
            .GreaterOrEquals(parameters.EarliestArrivalDateTimeUtc)
            .LowerOrEquals(parameters.LatestArrivalDateTimeUtc)
        );

        var result = _elasticClient.Search<VisitProjection>(s => s
            .Index("visits")
            .Type("visit")
            .Aggregations(a => a
                .Filter("my_filter_agg", f => f
                    .Filter(fd => buildingFilter && dateFilter)
                        .Aggregations(ta => ta.DateHistogram("my_date_histogram", h => h
                            .Field(p => p.ArrivalDateTimeUtc)
                            .Interval(parameters.DateInterval) // "day"
                            .TimeZone(NodaTimeHelpers.WindowsToIana(parameters.TimeZoneInfo)) // This is a critical piece of the equation.
                            .MinimumDocumentCount(0)
                        )
                    )
                )
            )
        );

        return result.Aggs.Nested("my_filter_agg").DateHistogram("my_date_histogram");
    }
}

// Returns [{Date: 12/22/2015 12:00:00 AM, DocCount: 1}]
Run Code Online (Sandbox Code Playgroud)

现在想象我改变了一点.想象一下,我在文档中添加了一个新字段:

{
               "id": "c223a991-b4e7-4333-ba45-a576010b568b",
// other properties
               "buildingId": "48da1a81-fa73-4d4f-aa22-a5750162ed1e",
               "arrivalDateTimeUtc": "2015-12-22T21:15:00Z",
               "departureDateTimeUtc": "2015-12-23T22:00:00Z" // new property
}
Run Code Online (Sandbox Code Playgroud)

并假设我想返回以下内容:

// Returns [{Date: 12/22/2015 12:00:00 AM, DocCount: 1}, {Date: 12/23/2015 12:00:00 AM, DocCount: 1}]
Run Code Online (Sandbox Code Playgroud)

因为访问时间跨度为两天,我想要一个日期直方图,记录访问跨越的每一天的一个单位.

我如何使用NEST/Elastic Search进行此操作?


注1:除非有人说服我,否则我不认为收集范围内的所有文件并在中间层(或C#层)执行聚合/ bucketization和日期直方图是个好主意.

注2:此问题的时区方面至关重要,因为我需要根据给定的时区对计数进行bucketized.

Val*_*Val 4

一种方法是使用scripted_metric聚合并根据两个日期字段自行执行存储。相当复杂并且性能不佳,具体取决于您拥有的文档数量。

然而,另一个更简单的解决方案可能是使用单个日期字段,并将间隔的所有日期放入一个数组中(最先到达、最后离开以及中间的所有其他日期),如下所示:

{
     "id": "c223a991-b4e7-4333-ba45-a576010b568b",
     "buildingId": "48da1a81-fa73-4d4f-aa22-a5750162ed1e",
     "visitDateTimeUtc": ["2015-12-22T21:15:00Z", "2015-12-23T22:00:00Z" ]
}
Run Code Online (Sandbox Code Playgroud)

如果访问跨越三/四/等天,您可以用到达和离开之间的天数“填充”数组

{
     "id": "c223a991-b4e7-4333-ba45-a576010b568b",
     "buildingId": "48da1a81-fa73-4d4f-aa22-a5750162ed1e",
     "visitDateTimeUtc": ["2015-12-22T21:15:00Z", "2015-12-23T22:00:00Z", "2015-12-24T22:00:00Z", "2015-12-25T22:00:00Z" ]
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,您的聚合将考虑该时间间隔的所有日期date_histogram