如何将此 MongoDB(聚合)查询写入 C#

Ani*_*nil 8 c# mongodb aggregation-framework mongodb-.net-driver

我需要使用 MongoDB 中的运算符执行分组$max。我找出了在 MongoDB 数据库中运行的查询,但无法使用 C# 编写相同的查询。

db.getCollection('Employee').aggregate(
[  
    {$unwind : "$Projects"},
    {
        "$group" : {
            "_id" : "$EmpId",
            "LastUpdated" : {"$max" : "$Projects.LastUpdated"}
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

下面的 C# 代码出现错误:

“项目”不是有效的财产。

db.getCollection('Employee').aggregate(
[  
    {$unwind : "$Projects"},
    {
        "$group" : {
            "_id" : "$EmpId",
            "LastUpdated" : {"$max" : "$Projects.LastUpdated"}
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

Yon*_*hun 15

假设这是您的示例数据:

[{
  "EmpId": 1,
  "Projects": [
    {
      "LastUpdated": {
        "$date": "2021-10-22T16:00:00Z"
      }
    },
    {
      "LastUpdated": {
        "$date": "2021-11-07T16:00:00Z"
      }
    },
    {
      "LastUpdated": {
        "$date": "2022-01-22T16:00:00Z"
      }
    }
  ]
}]
Run Code Online (Sandbox Code Playgroud)

这是你的模型类:

public class Employee
{
    public int EmpId { get; set; }
    public List<EmployeeProject> Projects { get; set; }
}

public class EmployeeProject
{
    public DateTime UpdatedDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

要使用该Projects属性,您需要将集合指定为Project类型:

_db.GetCollection<Employee>("Employee")
Run Code Online (Sandbox Code Playgroud)

方案1:AggregateFluent和BsonDocument混合使用

var result = _db.GetCollection<Employee>("Employee")
                .Aggregate()
                .Unwind(i => i.Projects)
                .Group(new BsonDocument
                {
                    { "_id", "$EmpId" },
                    { "LastUpdated", new BsonDocument("$max", "$Projects.LastUpdated") }
                })
                .ToList();
Run Code Online (Sandbox Code Playgroud)

方案二:充分利用AggregateFluent

先决条件:

  • 需要创建一个用于 unwinded 的模型Project
public class UnwindEmployeeProject
{
    public int EmpId { get; set; }
    public EmployeeProject Projects { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
var result = _db.GetCollection<Employee>("Employee")
               .Aggregate()
               .Unwind<Employee, UnwindEmployeeProject>(i => i.Projects)
               .Group(
                   k => k.EmpId,
                   g => new
                   {
                       EmpId = g.Key,
                       LastUpdated = g.Max(x => x.Projects.LastUpdated)
                   })
               .ToList();
Run Code Online (Sandbox Code Playgroud)

方案三:充分利用BsonDocument

使用 Mongo Compass,您可以将查询导出到 C#

PipelineDefinition<Employee, BsonDocument> pipeline = new BsonDocument[]
{
    new BsonDocument("$unwind", "$Projects"),
    new BsonDocument("$group",
        new BsonDocument
        {
            { "_id", "$EmpId" },
            { "LastUpdated",
                new BsonDocument("$max", "$Projects.LastUpdated") }
        })
};

var result = _db.GetCollection<Employee>("Employee")
                .Aggregate(pipeline)
                .ToList();  
Run Code Online (Sandbox Code Playgroud)

输出