如何格式化MongoDB单层及双层嵌套数组查询结果?
MongoDB嵌套数组输出格式控制问题
我需要格式化MongoDB查询的输出结果。执行以下查询:
db.getCollection("books").find({})
返回的原始数据结构如下:
{ title: "book 1", numberOfReaders: 3, characters: [{ name: "annie", age: 3, height: 60, items: { itemName: "watch", itemDesc: "tells time" } },{ name: "bob", age: 5, height: 100, items: { itemName: "sword", itemDesc: "a long metallic sword" } }] }
我知道可以通过投影操作控制输出,比如下面的查询能直接排除characters数组:
db.getCollection("books").find({}, { title: "$title", numberOfReaders: "$numberOfReaders" })
返回结果:
{ title: "book 1", numberOfReaders: 3 // 已排除characters数组 }
现在需要解决两个场景的格式控制:
- 保留
characters数组,但移除每个character对象的age、height和itemDesc字段,得到目标结果:
{ title: "book 1", numberOfReaders: 3, characters: [{ // 移除了age、height和itemDesc name: "annie", items: { itemName: "watch" } },{ name: "bob", items: { itemName: "sword" } }] }
- 若
characters是双层数组结构(characters: [[{...}, {...}]]),如何实现同样的字段过滤,得到目标结果:
{ title: "book 1", numberOfReaders: 3, characters: [[{ // 双层数组下移除指定字段 name: "annie", items: { itemName: "watch" } },{ name: "bob", items: { itemName: "sword" } }]] }
解决方案
1. 单层characters数组的处理
直接用MongoDB的投影语法就能实现,有两种方式可选:
方式一:明确指定需要保留的字段
db.getCollection("books").find({}, { title: 1, numberOfReaders: 1, "characters.name": 1, "characters.items.itemName": 1 })
方式二:明确排除不需要的字段
db.getCollection("books").find({}, { title: 1, numberOfReaders: 1, "characters.age": 0, "characters.height": 0, "characters.items.itemDesc": 0 })
注意:投影规则里不能同时混合使用“包含(1)”和“排除(0)”(_id字段例外),所以二选一即可,两种方式都能得到目标输出。
2. 双层characters数组的处理
双层嵌套数组没法用普通投影直接处理,需要用聚合管道的$map操作符来逐层遍历数组并过滤字段:
db.getCollection("books").aggregate([ { $project: { title: 1, numberOfReaders: 1, characters: { $map: { input: "$characters", as: "outerArr", in: { $map: { input: "$$outerArr", as: "char", in: { name: "$$char.name", items: { itemName: "$$char.items.itemName" } } } } } } } } ])
逻辑说明:
- 外层
$map遍历characters的第一层数组(也就是每个内层数组) - 内层
$map遍历每个内层数组里的character对象 - 对每个character对象,只保留
name和items.itemName字段,自动剔除其他不需要的字段
这样就能在双层数组结构下得到想要的输出格式。
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

