public IEnumerable <FieldDensityDto> GetFieldDensity(string fieldName, string query, DateTime start, DateTime end, int limit, int skip) { BsonDocument matchQuery = BsonDocument.Parse(query); BsonDocument matchDate = new BsonDocument().Add("TimeStamp", new BsonDocument().Add("$gte", start.ToUniversalTime()).Add("$lte", end.ToUniversalTime())); BsonDocument match = new BsonDocument("$match", matchDate.Merge(matchQuery)); BsonDocument loglimitQuery = new BsonDocument().Add("$limit", 10000); BsonDocument logskipQuery = new BsonDocument().Add("$skip", 0); BsonDocument resultlimitQuery = new BsonDocument().Add("$limit", limit); BsonDocument resultskipQuery = new BsonDocument().Add("$skip", skip); BsonDocument sortQuery = new BsonDocument().Add("$sort", new BsonDocument().Add("count", -1)); BsonDocument groupById = new BsonDocument() .Add("$group", new BsonDocument().Add("_id", "$" + fieldName) .Add("count", new BsonDocument().Add("$sum", 1)) .Add("firstHit", new BsonDocument().Add("$min", "$TimeStamp")) .Add("lastHit", new BsonDocument().Add("$max", "$TimeStamp"))); var sw = Stopwatch.StartNew(); Debug.WriteLine("match : " + match.ToString()); Debug.WriteLine(matchQuery.ToString()); Debug.WriteLine(loglimitQuery.ToString()); Debug.WriteLine(logskipQuery.ToString()); Debug.WriteLine(groupById.ToString()); Debug.WriteLine(sortQuery.ToString()); Debug.WriteLine(resultlimitQuery.ToString()); Debug.WriteLine(resultskipQuery.ToString()); IEnumerable <BsonDocument> groups = _context.Aggregate("logs", match, groupById, sortQuery, resultlimitQuery, resultskipQuery); Debug.WriteLine(fieldName + " : " + sw.ElapsedMilliseconds + "ms"); var result = new List <FieldDensityDto>(); foreach (BsonDocument group in groups) { if (!group.Contains("_id")) { continue; } if (group["_id"].IsBsonNull) { continue; } result.Add(new FieldDensityDto { FieldName = TryGetValue(group, "_id").AsString, Total = group["count"].AsInt32, FirstHit = ToLocal(group["firstHit"].ToUniversalTime()), LastHit = ToLocal(group["lastHit"].ToUniversalTime()) }); } return(result); }