如何从Mongoose查询返回的对象数组中提取图片链接?
问题:如何将Mongoose返回的嵌套图片链接数组扁平化?
我使用Node.js和Express从Mongoose数据库获取数据,当前得到的响应为嵌套结构:
[ { "images": [ { "link": "https://just-incase-from-a-far/yop.png" }, { "link": "https://main-link-test/lol.png" } ] }, { "images": [ { "link": "https://example-link/happy.jpg" }, { "link": "https://example-link/angry.jpg" }, { "link": "https://example-link/sad.png" } ] } ]
但我希望得到所有图片链接组成的一维数组:
[ "https://just-incase-from-a-far/yop.png", "https://main-link-test/lol.png", "https://example-link/happy.jpg", "https://example-link/angry.jpg", "https://example-link/sad.png" ]
当前实现的代码如下:
exports.getProducts = async (req,res) => { const result = await Product .find({isEmpty:false}) .select("-_id -createdAt -__v -isEmpty") .exec() if(!result) return res.status(400).json({ data: 'No product found' }); if(result.err) return res.json({ err: err }); return res.json(result); }
解决方案
有两种可行的实现方式,可根据需求选择:
方式一:使用Mongoose聚合查询(数据库层面处理)
这种方式直接在数据库端完成数据转换,适合数据量较大的场景,性能更优:
exports.getProducts = async (req,res) => { try { const imageLinks = await Product.aggregate([ // 筛选isEmpty为false的文档 { $match: { isEmpty: false } }, // 将images数组拆分为单个文档 { $unwind: "$images" }, // 将每个文档替换为images.link的值 { $replaceRoot: { newRoot: "$images.link" } } ]); if(!imageLinks.length) { return res.status(400).json({ data: 'No product found' }); } return res.json(imageLinks); } catch(err) { return res.json({ err: err.message }); } }
方式二:查询后用JavaScript数组方法处理
如果更倾向于在应用层处理数据,可以使用数组的flatMap和map方法完成扁平化:
exports.getProducts = async (req,res) => { try { const result = await Product .find({isEmpty:false}) .select("-_id -createdAt -__v -isEmpty") .exec() if(!result.length) { return res.status(400).json({ data: 'No product found' }); } // 提取所有图片链接并扁平化数组 const imageLinks = result.flatMap(item => item.images.map(img => img.link)); return res.json(imageLinks); } catch(err) { return res.json({ err: err.message }); } }
注意事项
- 原代码中的
if(result.err)逻辑错误,find方法返回的是文档数组,不会携带err属性,改用try-catch捕获异步查询中的错误更可靠。 - 判断是否有数据时,用
result.length替代!result,因为find即使没有匹配数据也会返回空数组,不会返回null。
内容的提问来源于stack exchange,提问作者Otis
相关产品推荐
相关产品推荐

