如何使用 C# 和 Mongo 根据日期过滤和获取最后一个条目

How to Filter and get last entry based on date using C# and Mongo

这是 json 文件的一个片段,该文件记录了不同部门的多个学生的刷卡记录。根据每个学生进入教室的时间,他们将有多个条目。查询需要根据学生id和部门名称的列表获取最新的。

{ 
[
 {
      "studentid"; "stu-1234",
      "dept" : "geog",
      "teacher_id" : 1, 
      "Carddetails": 
     { 
        "LastSwipeTimestamp": "2021-11-25T10:50:00.5230694Z"
     }
 },

 {
      "studentid"; "stu-1234",
      "dept" : "geog",
      "teacher_id" : 2, 
      "Carddetails": 
     { 
        "LastSwipeTimestamp": "2021-11-25T11:50:00.5230694Z"
     }
 },
 {
      "studentid"; "stu-abc",
      "dept" : "geog",
      "teacher_id" : 11, 
      "Carddetails": 
     { 
        "LastSwipeTimestamp": "2021-11-25T09:15:00.5230694Z"
     }
 },
 {
      "studentid"; "stu-abc",
      "dept" : "geog",
      "teacher_id" : 21, 
      "Carddetails": 
     { 
        "LastSwipeTimestamp": "2021-11-25T11:30:00.5230694Z"
     }
 }
]
}

根据上次刷卡时间戳,查询需要从 geog 部门获取 studentID: stu-abcstu-1234。在这种情况下,它将是 stu-abc: 2021-11-25T11:30:00.5230694Zstu-1234:2021-11-25T11:50:00.5230694Z 分别。

到目前为止,这是我的代码

string [] students = {'stu-abc', 'stu-1234'}
string dept = "geog";
var filter = Builders<BsonDocument>.Filter.In("studentid", students )
                    & Builders<BsonDocument>.Filter.Eq("dept", dept);

_collections.Find(filter).Sort(Builders<BsonDocument>.Sort.Ascending("{\"LastSwipeTimestamp\":-1}")).FirstOrDefault()

但这只给我一条记录stu-1234:2021-11-25T11:50:00.5230694Z

如何同时获得两者?

从你的要求来看,我觉得Aggregation pipeline更合适

[{
    $match: {
        "studentid": {
            "$in": [
                "stu-abc",
                "stu-1234"
            ]
        },
        "dept": "geog"
    }
}, {
    $sort: {
        "Carddetails.LastSwipeTimestamp": -1
    }
}, {
    $group: {
        "_id": {
            "studentid": "$studentid",
            "dept": "$dept"
        },
        "Carddetails": {
            $first: "$Carddetails"
        }
    }
}, {
    $project: {
        _id: 0,
        "studentid": "$_id.studentid",
        "dept": "$_id.dept",
        "Carddetails": "$Carddetails"
    }
}]

Sample Mongo Playground


将 MongoDB 查询转换为 Mongo .NET 驱动程序如下:

string[] students = { "stu-abc", "stu-1234" };
string dept = "geog";

var pipeline = new BsonDocument[]
{
    new BsonDocument("$match",
    new BsonDocument
    {
        { "studentid",
            new BsonDocument("$in",
                BsonArray.Create(students))
            },
            { "dept", dept }
        }),
    new BsonDocument("$sort",
    new BsonDocument("Carddetails.LastSwipeTimestamp", -1)),
    new BsonDocument("$group",
        new BsonDocument
        {
            { "_id",
                new BsonDocument
                {
                    { "studentid", "$studentid" },
                    { "dept", "$dept" }
                } 
            },
            { "Carddetails",
                new BsonDocument("$first", "$Carddetails") 
            }
        }
    ),
    new BsonDocument("$project",
        new BsonDocument
        {
            { "_id", 0 },
            { "studentid", "$_id.studentid" },
            { "dept", "$_id.dept" },
            { "Carddetails", "$Carddetails" }
        }
    )
};

var result = collection.Aggregate<BsonDocument>(pipeline)
    .ToList();

Console.WriteLine(result.ToJson());

Output