如何在MongoDB控制台输出筛选后的指定月份分类对象
问题
我有包含分类信息的用户对象,每个分类包含成本与添加日期(日、月、年)字段,所有用户都有这类分类。现在需要在控制台展示用户Tom所有月份为"08"的分类,但当前代码会输出Tom的完整用户对象,请问该如何修改?
现有代码:
mongoClient.connect(function (err, client) { const db = client.db("expensesdb"); const collection = db.collection("users"); if (err) return console.log(err); collection .find({ name: "Tom", }) .toArray(function (err, results) { console.log(results); client.close(); }); });
数据结构示例:
categories: { products: { cost: "50$", date: { day: `13`, month: `08`, year: `2022`, }, }, health: { cost: "550$", date: { day: `13`, month: `08`, year: `2022`, }, }, entertainment: { cost: "100$", date: { day: `16`, month: `05`, year: `2022`, }, }, },
解决方案
由于你的categories是键值对结构而非数组,有两种实现思路:
方法一:查询后在JS端过滤
先获取Tom的完整数据,再在客户端筛选符合月份条件的分类,适合数据量较小的场景:
修改后的代码:
mongoClient.connect(function (err, client) { const db = client.db("expensesdb"); const collection = db.collection("users"); if (err) return console.log(err); collection .find({ name: "Tom" }) .toArray(function (err, results) { if (err) return console.log(err); // 取出Tom的分类数据,避免空值报错 const tomCategories = results[0]?.categories || {}; // 筛选出月份为"08"的分类,转回键值对格式 const filteredCategories = Object.fromEntries( Object.entries(tomCategories).filter(([_, category]) => { return category.date?.month === "08"; }) ); console.log(filteredCategories); client.close(); }); });
方法二:MongoDB聚合查询在服务端过滤
如果数据量较大,推荐在数据库层面完成过滤,减少客户端与服务端的数据传输:
mongoClient.connect(function (err, client) { const db = client.db("expensesdb"); const collection = db.collection("users"); if (err) return console.log(err); collection .aggregate([ // 匹配目标用户Tom { $match: { name: "Tom" } }, // 将categories的键值对转为数组结构,方便后续过滤 { $project: { categories: { $objectToArray: "$categories" } } }, // 筛选出月份等于"08"的分类 { $project: { categories: { $filter: { input: "$categories", as: "cat", cond: { $eq: ["$$cat.v.date.month", "08"] } } } } }, // 将过滤后的数组转回键值对格式 { $project: { categories: { $arrayToObject: "$categories" } } } ]) .toArray(function (err, results) { if (err) return console.log(err); console.log(results[0]?.categories || {}); client.close(); }); });
内容的提问来源于stack exchange,提问作者userName
相关产品推荐
相关产品推荐

