如何在MongoDB聚合中移除指定日期后的非目标嵌套ID键
可以用MongoDB聚合实现该需求
完全可以通过MongoDB聚合管道完成这个操作,核心思路是把嵌套的对象结构转成数组进行过滤处理,再转回对象结构。以下是针对你的需求的具体实现方案:
需求回顾
原始文档结构:
{ "data": { "2023-02-01": { "123": { "price": 100 }, "234": { "price": 100 } }, "2023-02-02": { "123": { "price": 100 }, "234": { "price": 100 } }, "2023-02-03": { "123": { "price": 100 }, "234": { "price": 100 } } } }
目标ID列表:ids = [123],需要从指定日期(如2023-02-02)开始,移除该日期及之后子文档中不在ID列表内的键。
聚合管道实现
固定指定日期的情况
使用以下聚合管道,将target_date替换为你需要的起始日期:
db.collection.aggregate([ { $addFields: { data: { $arrayToObject: { $map: { input: { $objectToArray: "$data" }, as: "dateItem", in: { k: "$$dateItem.k", v: { $cond: [ { $gte: ["$$dateItem.k", "2023-02-02"] }, { $arrayToObject: { $filter: { input: { $objectToArray: "$$dateItem.v" }, as: "idItem", cond: { $in: [{ $toInt: "$$idItem.k" }, [123]] } } } }, "$$dateItem.v" ] } } } } } } }, // 如果需要更新原集合,添加$merge阶段 { $merge: { into: "collection", // 替换为你的集合名 on: "_id", whenMatched: "replace" } } ])
使用今日日期的情况
如果需要动态使用今日日期,可以在pymongo中先生成今日的日期字符串,再传入聚合管道:
from pymongo import MongoClient from datetime import datetime client = MongoClient() db = client.your_database collection = db.your_collection # 生成今日日期字符串,格式为YYYY-MM-DD target_date = datetime.today().strftime("%Y-%m-%d") ids = [123] pipeline = [ { "$addFields": { "data": { "$arrayToObject": { "$map": { "input": {"$objectToArray": "$data"}, "as": "dateItem", "in": { "k": "$$dateItem.k", "v": { "$cond": [ {"$gte": ["$$dateItem.k", target_date]}, { "$arrayToObject": { "$filter": { "input": {"$objectToArray": "$$dateItem.v"}, "as": "idItem", "cond": {"$in": [{"$toInt": "$$idItem.k"}, ids]} } } }, "$$dateItem.v" ] } } } } } } }, { "$merge": { "into": "your_collection", "on": "_id", "whenMatched": "replace" } } ] # 执行聚合 collection.aggregate(pipeline)
关键步骤说明
$objectToArray:把嵌套的对象(比如data下的日期对象、日期下的ID对象)转成[{k: 键名, v: 键值}]的数组结构,方便后续遍历过滤。$map:遍历日期数组,对每个日期项进行判断和处理。$cond:判断当前日期是否大于等于目标日期,是则过滤ID,否则保留原结构。$filter:针对目标日期及之后的子文档,筛选出ID在指定列表中的项。$arrayToObject:把处理后的数组转回对象结构,恢复原始的嵌套格式。$merge:将聚合处理后的结果写回原集合,实现文档更新。
执行后就能得到你预期的结果:
{ "data": { "2023-02-01": { "123": { "price": 100 }, "234": { "price": 100 } }, "2023-02-02": { "123": { "price": 100 } }, "2023-02-03": { "123": { "price": 100 } } } }
内容的提问来源于stack exchange,提问作者bambangkode
相关产品推荐
相关产品推荐

