MongoDB C#驱动程序 - 仅返回上次修改的行

时间:2016-09-27 11:37:57

标签: c# mongodb

数据: 该集合包含审计记录列表,我想从集合中返回最后修改的项目。

例如:

Audit Records

因此查询需要返回Audit 1235和1237 Only。

以下语句在Mongo Shell中有效并返回数据亚毫秒,我只需要弄清楚如何返回整个Collection项而不仅仅是Id。

db.Forms.aggregate(
{ $group: { _id: "$Id", lastModifiedId: { $last: "$_id" } } }
)

但是,我需要将其转换为C#Driver的语法。

我现在有以下内容,但它没有工作,并返回(缺少一个更好的术语)奇怪的数据(请参阅声明中的screencap)。

var results = collection.Aggregate()
.Group(new BsonDocument { { "_id", "$Id" }, { "lastModifiedId", new BsonDocument("$last", "_id") } })
.ToListAsync().Result.ToList();

Results

我当前的解决方案获取完整集合,然后通过扩展方法运行它以获取最新记录(列表是完整集合):

var lastModifiedOnlyList =
from listItem in list.OrderByDescending(_ => _.AuditId)
group listItem by listItem.Id into grp
select grp.OrderByDescending(listItem => listItem.AuditId)
.FirstOrDefault();

虽然这段代码有效,但由于从集合中返回大量数据,所以它非常慢,所以我需要在列表中进行分组,作为集合get / find的一部分。

如果我可以提供任何其他信息,请告诉我。

更新:借助Axel的帮助,我设法解决了问题:

var pipeline = new[] { new BsonDocument { { "$group", new BsonDocument { { "_id", "$Id" }, { "LastAuditId", new BsonDocument { { "$last", "$_id" } } } } } } };
var lastAuditIds = collection.Aggregate<Audit>(pipeline).ToListAsync().Result.ToList().Select(_=>_.LastAuditId);

我把它移到它自己的方法然后使用ID来收集集合项目,我的预测工作也是如此:

var forLastAuditIds = ForLastAuditIds(collection);

var limitedList = (
                projection != null
                    ? collection.Find(forLastAuditIds & filter, new FindOptions()).Project(projection)
                    : collection.Find(forLastAuditIds & filter, new FindOptions())
            ).ToListAsync().Result.ToList();

&#34;过滤器&#34;在这种情况下是Expression或BsonDocument。表现也很棒 - 整个事情的次要次数。谢谢你的帮助,Axel!

1 个答案:

答案 0 :(得分:1)

我认为你正在做一个额外的OrderBy,这应该做:

var lastModifiedOnlyList =
from listItem in list
group listItem by listItem.Id into grp
select grp.OrderByDescending(listItem => listItem.AuditId)
.FirstOrDefault();

编辑:

要在查询中获得性能,可以使用不同的聚合函数:

var match = new BsonDocument
{
    {
        "$group",
        new BsonDocument
            {
                { "_id", "$Id"  },
                { "lastModifiedId", new BsonDocument
                    {
                        {
                            "$last", "$_id"
                        }
                    }}
            }
    }
};

var pipeline = new[] { match };
var result = collection.Aggregate(pipeline);

这应该等同于您的Mongo Shell查询。