You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询MongoDB中嵌套数组最新首条元素状态为opened的文档

How to Query MongoDB Documents Where the Latest Event in an Array Has a Specific Status

Hey there! The core issue here is that your current query checks if any event matches the status, but you need to validate only the most recent event (sorted by date) in the events array. Let’s break down how to solve this with the MongoDB C# driver, depending on your MongoDB version:

Modern Approach (MongoDB 5.0+)

MongoDB 5.0 introduced the $sortArray operator, which simplifies this task drastically. We’ll use an aggregation pipeline to sort the events array, isolate the latest entry, and filter based on its status.

Here’s the C# implementation:

// Build the aggregation pipeline
var pipeline = new BsonDocument[]
{
    // Optional: Keep your existing regex filter as the first stage
    new BsonDocument("$match", new BsonDocument(
        "events.event", new BsonRegularExpression(searchString, "i")
    )),
    // Add a temporary field with events sorted by date (newest first)
    new BsonDocument("$addFields", new BsonDocument(
        "latestEvent", new BsonDocument("$first", 
            new BsonDocument("$sortArray", new BsonDocument
            {
                { "input", "$events" },
                { "sortBy", new BsonDocument("date", -1) } // -1 = descending order
            })
        )
    )),
    // Filter only documents where the latest event's status is "opened"
    new BsonDocument("$match", new BsonDocument(
        "latestEvent.status", "opened"
    )),
    // Optional: Clean up results by removing the temporary field
    new BsonDocument("$project", new BsonDocument("latestEvent", 0))
};

// Execute the aggregation
var results = await collection.Aggregate<Notification>(pipeline).ToListAsync();

Step-by-Step Breakdown:

  • $sortArray: Reorders the events array so the most recent entry (highest date value) is first.
  • $first: Extracts that top (latest) event into a temporary latestEvent field.
  • $match: Filters out any document where latestEvent.status isn’t "opened".
  • $project: Optional cleanup to remove the temporary field from your final results.

Alternative for Older MongoDB Versions (Pre-5.0)

If you’re stuck on a version before 5.0, use $unwind, $sort, and $group to isolate the latest event per document:

var pipeline = new BsonDocument[]
{
    // Keep your existing regex filter
    new BsonDocument("$match", new BsonDocument(
        "events.event", new BsonRegularExpression(searchString, "i")
    )),
    // Split the events array into individual documents
    new BsonDocument("$unwind", "$events"),
    // Sort by document ID and event date (newest first)
    new BsonDocument("$sort", new BsonDocument
    {
        { "_id", 1 },
        { "events.date", -1 }
    }),
    // Group back into original documents, retaining only the latest event
    new BsonDocument("$group", new BsonDocument
    {
        { "_id", "$_id" },
        { "subject", new BsonDocument("$first", "$subject") }, // Include all top-level fields you need
        { "latestEvent", new BsonDocument("$first", "$events") }
    }),
    // Filter for documents where the latest event is "opened"
    new BsonDocument("$match", new BsonDocument("latestEvent.status", "opened")),
    // Optional: Reconstruct the original document structure
    new BsonDocument("$project", new BsonDocument
    {
        { "_id", 1 },
        { "subject", 1 },
        { "events", new BsonDocument("$push", "$latestEvent") }
    })
};

var results = await collection.Aggregate<Notification>(pipeline).ToListAsync();

Note: In the $group stage, explicitly list all top-level fields from your Notification document that you want to preserve (like subject).

内容的提问来源于stack exchange,提问作者Master

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:33:12