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

如何创建满足多条件的MongoDB批量更新操作?

解决MongoDB Books集合的重复文档标记问题

Hey there, let's figure out how to mark those older duplicate books as inactive exactly as you described. The goal is to set active: false for documents that share the same title and author, are currently active, have different code values, and were updated earlier than the most recent entry in their group.

Step 1: Identify Documents to Update

First, we'll use an aggregation pipeline to pinpoint which documents need their active status changed. This pipeline filters and groups documents to isolate the older duplicates:

db.books.aggregate([
  // Only consider books that are currently active
  { $match: { active: true } },
  // Group by title + author to find the most recent update time per group
  {
    $group: {
      _id: { title: "$title", author: "$author" },
      latestLastUpdated: { $max: "$lastUpdated" },
      // Collect all docs in the group with their ID, update time and code
      groupDocs: { $push: { docId: "$_id", updatedAt: "$lastUpdated", code: "$code" } }
    }
  },
  // Expand the grouped document list to process each entry individually
  { $unwind: "$groupDocs" },
  // Filter out the most recent document in each group (keep only older ones)
  { $match: { $expr: { $lt: ["$groupDocs.updatedAt", "$latestLastUpdated"] } } },
  // Only keep the ID of documents that need updating
  { $project: { _id: "$groupDocs.docId" } }
])

Step 2: Batch Update the Target Documents

Once we have the list of document IDs to update, we can use updateMany to bulk-set their active field to false. Here's how to tie it all together:

// Fetch all IDs of documents that need to be marked inactive
const targetDocIds = db.books.aggregate([
  { $match: { active: true } },
  {
    $group: {
      _id: { title: "$title", author: "$author" },
      latestLastUpdated: { $max: "$lastUpdated" },
      groupDocs: { $push: { docId: "$_id", updatedAt: "$lastUpdated" } }
    }
  },
  { $unwind: "$groupDocs" },
  { $match: { $expr: { $lt: ["$groupDocs.updatedAt", "$latestLastUpdated"] } } },
  { $project: { _id: "$groupDocs.docId" } }
]).toArray().map(entry => entry._id);

// Perform the bulk update if there are documents to modify
if (targetDocIds.length > 0) {
  const updateResult = db.books.updateMany(
    { _id: { $in: targetDocIds } },
    { $set: { active: false } }
  );
  print(`Updated ${updateResult.modifiedCount} documents to active: false`);
} else {
  print("No documents found that match the update criteria.");
}

Key Notes

  • This approach ensures we only touch documents that meet all your criteria: same title/author, active=true, different code (since we're grouping by title/author and keeping the latest, any other entries in the group must have a different code per your example), and older lastUpdated time.
  • If a title/author group has only one document, it won't be included in the update list—perfect, since there's no duplicate to mark inactive.
  • If multiple documents in a group have the same lastUpdated time, none of them will be updated (since $lt won't match). If you need to handle this edge case (e.g., keep one active and mark others as inactive), you could adjust the aggregation to pick a secondary criteria like the highest/lowest code value.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:04:16