Beispiel #1
0
        public EventTermStatsResult GetTermsStats(DateTime utcStart, DateTime utcEnd, string term, string systemFilter, string userFilter = null, TimeSpan? displayTimeOffset = null, int max = 25, int desiredDataPoints = 10) {
            if (!displayTimeOffset.HasValue)
                displayTimeOffset = TimeSpan.Zero;

            var allowedTerms = new[] { "organization_id", "project_id", "stack_id", "tags", "version" };
            if (!allowedTerms.Contains(term))
                throw new ArgumentException("Must be a valid term.", "term");
            
            var filter = new ElasticSearchOptions<PersistentEvent>()
                .WithFilter(!String.IsNullOrEmpty(systemFilter) ? Filter<PersistentEvent>.Query(q => q.QueryString(qs => qs.DefaultOperator(Operator.And).Query(systemFilter))) : null)
                .WithQuery(userFilter)
                .WithDateRange(utcStart, utcEnd, "date")
                .WithIndicesFromDateRange();
            _client.EnableTrace();

            // if no start date then figure out first event date
            if (!filter.UseStartDate) {
                var result = _client.Search<PersistentEvent>(s => s.IgnoreUnavailable().Index(filter.Indices.Count > 0 ? String.Join(",", filter.Indices) : String.Concat(ElasticSearchRepository<PersistentEvent>.EventsIndexName, "-*")).Filter(d => filter.GetElasticSearchFilter()).SortAscending(ev => ev.Date).Take(1));

                var firstEvent = result.Hits.FirstOrDefault();
                if (firstEvent != null) {
                    utcStart = firstEvent.Source.Date.UtcDateTime;
                    filter.WithDateRange(utcStart, utcEnd, "date");
                    filter.WithIndicesFromDateRange();
                }
            }

            utcStart = filter.GetStartDate();
            utcEnd = filter.GetEndDate();

            var interval = GetInterval(utcStart, utcEnd, desiredDataPoints);
            var res = _client.Search<PersistentEvent>(s => s
                .SearchType(SearchType.Count)
                .IgnoreUnavailable()
                .Index(filter.Indices.Count > 0 ? String.Join(",", filter.Indices) : String.Concat(ElasticSearchRepository<PersistentEvent>.EventsIndexName, "-*"))
                .Aggregations(agg => agg
                    .Filter("filtered", f => f
                        .Filter(d => filter.GetElasticSearchFilter())
                        .Aggregations(filteredAgg => filteredAgg
                            .Terms("terms", t => t
                                .Field(term)
                                .Size(max)
                                .Aggregations(agg2 => agg2
                                    .DateHistogram("timelime", tl => tl
                                        .Field(ev => ev.Date)
                                        .MinimumDocumentCount(0)
                                        .Interval(interval.Item1)
                                        .TimeZone(HoursAndMinutes(displayTimeOffset.Value))
                                    )
                                    .Cardinality("unique", u => u
                                        .Field(ev => ev.StackId)
                                        .PrecisionThreshold(1000)
                                    )
                                    .Terms("new", u => u
                                        .Field(ev => ev.IsFirstOccurrence)
                                        .Exclude("F")
                                    )
                                    .Min("first_occurrence", o => o.Field(ev => ev.Date))
                                    .Max("last_occurrence", o => o.Field(ev => ev.Date))
                                )
                            )
                        )
                    )
                )
            );

            if (!res.IsValid) {
                Log.Error().Message("Retrieving term stats failed: {0}", res.ServerError.Error).Write();
                throw new ApplicationException("Retrieving term stats failed.");
            }

            _client.DisableTrace();


            var filtered = res.Aggs.Filter("filtered");
            if (filtered == null)
                return new EventTermStatsResult();

            var stats = new EventTermStatsResult {
                Total = filtered.DocCount
            };

            stats.Terms.AddRange(filtered.Terms("terms").Items.Select(i => {
                long count = 0;
                var timelineUnique = i.Cardinality("unique").Value;
                if (timelineUnique.HasValue)
                    count = (long)timelineUnique.Value;

                var item = new TermStatsItem {
                    Total = i.DocCount,
                    Unique = count,
                    Term = i.Key,
                    New = i.Terms("new").Items.Count > 0 ? i.Terms("new").Items[0].DocCount : 0
                };

                var firstOccurrence = i.Min("first_occurrence").Value;
                var lastOccurrence = i.Max("last_occurrence").Value;

                if (firstOccurrence.HasValue)
                    item.FirstOccurrence = firstOccurrence.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);

                if (lastOccurrence.HasValue)
                    item.LastOccurrence = lastOccurrence.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);

                item.Timeline.AddRange(i.DateHistogram("timelime").Items.Select(ti => new TermTimelineItem {
                    Date = ti.Date,
                    Total = ti.DocCount
                }));

                return item;
            }));

            stats.Start = utcStart.SafeAdd(displayTimeOffset.Value);
            stats.End = utcEnd.SafeAdd(displayTimeOffset.Value);

            return stats;
        }
Beispiel #2
0
        public EventTermStatsResult GetTermsStats(DateTime utcStart, DateTime utcEnd, string term, string query = null, TimeSpan? utcOffset = null, int max = 25, int desiredDataPoints = 10)
        {
            if (!utcOffset.HasValue)
                utcOffset = TimeSpan.Zero;

            var allowedTerms = new[] { "tags", "stack_id", "organization_id" };
            if (!allowedTerms.Contains(term))
                throw new ArgumentException("Must be a valid term.", "term");

            var options = new ElasticSearchOptions<PersistentEvent>().WithQuery(query).WithDateRange(utcStart, utcEnd, "date").WithIndicesFromDateRange();
            _client.EnableTrace();

            var interval = GetInterval(utcStart, utcEnd, desiredDataPoints);
            var res = _client.Search<PersistentEvent>(s => s
                .SearchType(SearchType.Count)
                .IgnoreUnavailable()
                .Index(String.Join(",", options.Indices))
                .Aggregations(agg => agg
                    .Filter("filtered", f => f
                        .Filter(d => options.GetElasticSearchFilter())
                        .Aggregations(filteredAgg => filteredAgg
                            .Terms("terms", t => t
                                .Field(term)
                                .Size(max)
                                .Aggregations(agg2 => agg2
                                    .DateHistogram("timelime", tl => tl
                                        .Field(ev => ev.Date)
                                        .MinimumDocumentCount(0)
                                        .Interval(interval.Item1)
                                        .TimeZone(HoursAndMinutes(utcOffset.Value))
                                    )
                                    .Cardinality("unique", u => u
                                        .Field(ev => ev.StackId)
                                        .PrecisionThreshold(1000)
                                    )
                                    .Terms("new", u => u
                                        .Field(ev => ev.IsFirstOccurrence)
                                        .Exclude("F")
                                    )
                                    .Min("first_occurrence", o => o.Field(ev => ev.Date))
                                    .Max("last_occurrence", o => o.Field(ev => ev.Date))
                                )
                            )
                        )
                    )
                )
            );

            if (!res.IsValid) {
                Log.Error().Message("Retrieving term stats failed: {0}", res.ServerError.Error).Write();
                throw new ApplicationException("Retrieving term stats failed.");
            }

            _client.DisableTrace();

            var stats = new EventTermStatsResult {
                Total = res.Aggs.Filter("filtered").DocCount,
            };

            stats.Terms.AddRange(res.Aggs.Filter("filtered").DateHistogram("terms").Items.Select(i => {
                long count = 0;
                var timelineUnique = i.Cardinality("unique").Value;
                if (timelineUnique.HasValue)
                    count = (long)timelineUnique.Value;

                var item = new TermStatsItem {
                    Total = i.DocCount,
                    Unique = count,
                    New = i.Terms("new").Items.Count > 0 ? i.Terms("new").Items[0].DocCount : 0
                };

                var firstOccurrence = i.Min("first_occurrence").Value;
                var lastOccurrence = i.Max("last_occurrence").Value;

                if (firstOccurrence.HasValue)
                    item.FirstOccurrence = firstOccurrence.Value.ToDateTime();

                if (lastOccurrence.HasValue)
                    item.LastOccurrence = lastOccurrence.Value.ToDateTime();

                item.Timeline.AddRange(i.DateHistogram("timelime").Items.Select(ti => new TermTimelineItem {
                    Date = ti.Date,
                    Total = ti.DocCount
                }));

                return item;
            }));

            stats.Start = utcStart.Add(utcOffset.Value);
            stats.End = utcEnd.Add(utcOffset.Value);

            return stats;
        }