MongoDB查询:如何仅返回匹配数组元素的val字段值?
解决方案
方法1:用find()加投影返回匹配的数组元素
直接在find()的第二个参数里指定投影规则,只保留符合条件的attr元素,同时屏蔽其他字段:
db.myTable.find( {'id': 123, 'attr.name': 'Need Find'}, {'attr.$': 1, _id: 0} )
返回结果:
{ "attr": [ {"name": "Need Find", "val": "I Need This Value"} ] }
注意:你的原查询里把
id写成了字符串'123',但数据里的id是数字类型,得改成123才能匹配到目标文档。
方法2:用聚合管道直接提取val值
如果想直接拿到val的内容,聚合管道是更合适的选择,步骤清晰精准:
db.myTable.aggregate([ // 先筛选出id为123且包含目标attr元素的文档 {$match: {'id': 123, 'attr.name': 'Need Find'}}, // 展开attr数组,把每个数组元素拆成单独文档 {$unwind: '$attr'}, // 再次筛选出数组里name为Need Find的元素 {$match: {'attr.name': 'Need Find'}}, // 只保留val字段,去掉默认的_id {$project: {'val': '$attr.val', _id: 0}} ])
返回结果:
{ "val": "I Need This Value" }
方法3:用$filter+$map的聚合写法(更高效)
不想用$unwind的话,可以用数组操作符直接在投影阶段过滤提取:
db.myTable.aggregate([ {$match: {'id': 123}}, {$project: { _id: 0, val: { // 取过滤后的第一个元素的val $arrayElemAt: [ // 把过滤后的元素映射成val值 {$map: { input: {$filter: { input: '$attr', cond: {$eq: ['$$this.name', 'Need Find']} }}, as: 'item', in: '$$item.val' }}, 0 ] } }} ])
直接返回:
{ "val": "I Need This Value" }
MongoDB Compass里的操作步骤
打开Compass连接到数据库后:
- 选中
myTable集合 - 切换到「聚合」标签页
- 逐个添加上面聚合管道里的每个阶段(每个阶段对应一个步骤)
- 点击「运行」就能看到预期结果
内容的提问来源于stack exchange,提问作者Pavel Cikota
相关产品推荐
相关产品推荐

