Как получить последнюю запись в каждой группе с помощью MongoDB? - PullRequest
0 голосов
/ 08 мая 2020

Вот пример коллекции Mon go.

{
    "_id" : ObjectId("5ea3e01bd249221168f5545a"),
    "_ts" : {
        "$date" : 1587798043115
    },
    "Path" : "AAA",
    "Status" : "compiling"
}
{
    "_id" : ObjectId("5ea3e058d249221168f5545b"),
    "_ts" : {
        "$date" : 1587798165842
    },
    "Path" : "BBB",
    "Status" : "running"
}
{
    "_id" : ObjectId("5ea3e058d249221168f5545c"),
    "_ts" : {
        "$date" : 1587798104120
    },
    "Path" : "AAA",
    "Status" : "running"
}
{
    "_id" : ObjectId("5ea3e058d249221168f5545d"),
    "_ts" : {
        "$date" : 1587798104120
    },
    "Path" : "CCC",
    "Status" : "compiling"
}

И у меня есть класс jobStatus следующим образом:

    public class JobStatusEntity
    {
        [BsonId]
        public ObjectId Id { get; set; }

        [BsonElement("_ts")]
        public DateTime EntityTimestamp { get; set; } = DateTime.UtcNow;

        public string Path { get; set; } = string.Empty;

        public string Status { get; set; } = string.Empty;

    }

MongoDB.Driver - здесь используется 2.10.2.

Я хочу запросить эту коллекцию с предоставленным списком путей ( jobPathList ), а затем получить самую последнюю информацию о статусе задания. В настоящее время я использую следующий запрос для получения результатов.

var allAppendedJobStatusEntities = await _jobStatusCollection.AsQueryable()
    .Where(x => x.EntityTimestamp > queryStartTime && jobPathList.Contains(x.Path))
    .OrderBy(x => x.EntityTimestamp)
    .GroupBy(x => x.Path)
    .Select(p => new JobStatusEntity
    {
        Path = p.Last().Path,
        Status = p.Last().Status,
        EntityTimestamp = p.Last().EntityTimestamp,
    }).ToListAsync();

Кажется, этот запрос может получить результат правильно, но я сомневаюсь, что это лучшая практика, потому что я заметил использование jobPathList.Contains ( x.Path) принадлежит System.Linq вместо MongoDB.Driver.Linq .

Я нахожу некоторые ответы, в которых используется следующий фильтр для фильтрации результатов . Итак, Вопрос 1 , есть ли между ними разница?

var filter = Builders<JobStatusEntity>.Filter.Gt(x => x.EntityTimestamp, queryStartTime)
    & Builders<JobStatusEntity>.Filter.In(x => x.Path, jobPathList);
var res = (await _jobInfoCollection.FindAsync(filter)).ToList();

И Вопрос 2 , я также заметил, что в некоторых ответах сказано Aggregrate можно использовать здесь. Но я не знаю, как получить последнюю. Если кто-то может привести мне пример. Я буду признателен, если кто-нибудь сможет дать мне некоторое представление.

...