为数组中的每个ID查找TOP(1)

时间:2019-10-09 15:13:53

标签: c# .net mongodb

我有一个大型(60m +)文档集合,其中每个ID都有许多按时间顺序排列的记录。每个记录都有一个IMEI标识符,我正在寻找给定List<Imei>中每个IMEI的最新记录。

当前正在使用蛮力方法,在此方法中,我为每个IMEI创建一个循环,并在最上面的记录中yield创建一个循环,然后在循环结束后返回完整的集合。因此:

        List<BsonDocument> documents = new List<BsonDocument>();

        foreach(var config in imeiConfigs)
        {
            var filter = GetImeiFilter(config.IMEI);
            var sort = GetImeiSort();
            var data = _historyCollection.Find(filter).Sort(sort).Limit(1).FirstOrDefault();

            documents.Add(data);
        }

最终结果是一个List<BsonDocument>,其中每个BsonDocument都包含最新的IMEI,但性能不高。如果imeiConfigs太大,则查询会花费很长时间运行并返回,因为文档很大。

是否有一种方法可以为单个TOP 1中的每个IMEI选择一个<Alt> <Numpad: 0 0 9>,而不是像我上面这样的强行使用?

2 个答案:

答案 0 :(得分:0)

曾尝试使用LINQ Take 功能?

        List documents = new List();

foreach(var config in imeiConfigs) { var filter = GetImeiFilter(config.IMEI); var sort = GetImeiSort(); var data = _historyCollection.Find(filter).Sort(sort).Take(1).FirstOrDefault(); documents.Add(data); }

https://docs.microsoft.com/es-es/dotnet/api/system.linq.enumerable.take?view=netframework-4.8

答案 1 :(得分:0)

我认为效果不佳来自“排序(排序)”,因为排序会迫使它遍历所有集合。

但是也许您可以通过并行来提高时间性能。

List<BsonDocument> documents;

documents =  imeiConfigs.AsParallel().Select((config) =>
{
    var filter = GetImeiFilter(config.IMEI);
    var sort = GetImeiSort();
    var data = _historyCollection.Find(filter).Sort(sort).Limit(1).FirstOrDefault();

    return data;
}).ToList();