Filter record from collection “OperationSession”, sort by “WorldId” descending, then group by “WorldId”, then pick first record from each group, then sort result:
Way #1:
db.getCollection('OperationSession').aggregate( [ { "$match": {"ActivityId":74,"GameId":2109} }, { "$sort":{ "CreateTime" : -1} }, { "$group": { _id:"$WorldId", SessionId:{"$first": "$_id" }, GameId:{"$first": "$GameId" }, WorldId:{"$first": "$WorldId" }, ActivityId:{"$first": "$ActivityId" }, Type:{"$first": "$Type" }, Status:{"$first": "$Status" }, ActivityStatus:{"$first": "$ActivityStatus" } } }, { "$sort":{ "WorldId" : 1} }, { "$skip": 20}, { "$limit": 10} ] )
Way #2:
db.OperationSession.aggregate() .match({"ActivityId":74,"GameId":2109}) .sort({"CreateTime":-1}) .group({ "_id":"$WorldId", "SessionId":{"$first": "$_id" }, "GameId":{"$first": "$GameId" }, "WorldId":{"$first": "$WorldId" }, "ActivityId":{"$first": "$ActivityId" }, "Type":{"$first": "$Type" }, "Status":{"$first": "$Status" }, "ActivityStatus":{"$first": "$ActivityStatus" } }) .sort({"WorldId":1}) .skip(20) .limit(10)
In C#:
collection.Aggregate<DataEntity.OperationSession>() .Match(s => s.ActivityId == 74 && s.GameId == 2109) .SortByDescending(s => s.CreateTime) .Group( s => s.WorldId, s => new Interface.OperationSession { SessionId = s.Select(x => x.Id).First(), GameId = s.Select(x => x.GameId).First(), WorldId = s.Select(x => x.WorldId).First(), ActivityId = s.Select(x => x.ActivityId).First(), Type = s.Select(x => x.Type).First(), Status = s.Select(x => x.Status).First(), ActivityStatus = s.Select(x => x.ActivityStatus).First() }) .SortBy(s => s.WorldId) .Skip(20) .Limit(10).ToList();