MongoDB技术问题:如何根据cod字段查询三级子数组regis中的单个结果
从MongoDB数组中根据指定字段匹配并返回单个元素
想要从你的MongoDB文档里,根据cod字段从regis数组中取出单个匹配的元素?这里有几种实用的方法,你可以根据自己的MongoDB版本和需求来选择:
首先先确认你的目标文档结构:
{ "_id" : "exportadores", "instancia" : ISODate("2018-03-23T11:36:32.296+0000"), "dwFatPDFs" : { "regis" : [ { "cod" : "A1", "idFat" : NumberLong(15772), "data" : ISODate("2018-04-13T12:33:44.149+0000"), "ipPm" : "192.168.0.1" }, { "cod" : "A2", "idFat" : NumberLong(15772), "data" : ISODate("2018-04-13T13:54:26.477+0000"), "ipPm" : "192.168.0.1" } ] } }
方法1:用投影(Projection)中的$elemMatch快速筛选
这个方法适合需要保留原文档结构,只提取数组中第一个匹配元素的场景:
db.collection.find( // 先匹配到目标文档,同时确保数组里存在cod为"A1"的元素 { "_id": "exportadores", "dwFatPDFs.regis.cod": "A1" }, // 用$elemMatch指定只返回数组中匹配的元素 { "dwFatPDFs.regis": { "$elemMatch": { "cod": "A1" } } } )
返回结果会保留原文档的层级,但regis数组里只会有你要的那个元素:
{ "_id" : "exportadores", "dwFatPDFs" : { "regis" : [ { "cod" : "A1", "idFat" : NumberLong(15772), "data" : ISODate("2018-04-13T12:33:44.149+0000"), "ipPm" : "192.168.0.1" } ] } }
方法2:聚合管道直接返回匹配元素(MongoDB 3.2+推荐)
如果希望直接拿到匹配的元素本身,不需要嵌套在原文档里,可以用$filter结合$arrayElemAt,再通过$replaceRoot重构结果:
db.collection.aggregate([ // 第一步:定位到目标文档 { "$match": { "_id": "exportadores" } }, // 第二步:过滤regis数组,取出cod为"A1"的元素,再取第一个(确保单个结果) { "$project": { "matchedItem": { "$arrayElemAt": [ { "$filter": { "input": "$dwFatPDFs.regis", "cond": { "$eq": ["$$this.cod", "A1"] } } }, 0 ] } } }, // 第三步:把匹配的元素作为根文档返回 { "$replaceRoot": { "newRoot": "$matchedItem" } } ])
执行后会直接返回你需要的单个元素:
{ "cod" : "A1", "idFat" : NumberLong(15772), "data" : ISODate("2018-04-13T12:33:44.149+0000"), "ipPm" : "192.168.0.1" }
方法3:旧版本MongoDB的兼容方案(用$unwind)
如果你的MongoDB版本低于3.2,没有$filter,可以用$unwind先展开数组,再筛选匹配项:
db.collection.aggregate([ { "$match": { "_id": "exportadores" } }, // 展开regis数组,把每个数组元素变成独立文档 { "$unwind": "$dwFatPDFs.regis" }, // 筛选出cod为"A1"的文档 { "$match": { "dwFatPDFs.regis.cod": "A1" } }, // 把匹配的元素作为根文档返回 { "$replaceRoot": { "newRoot": "$dwFatPDFs.regis" } } ])
注意:如果regis数组里有多个cod为"A1"的元素,这个方法会返回多个结果。如果你的cod是唯一标识,就不用担心这个问题。
内容的提问来源于stack exchange,提问作者Myller M
相关产品推荐
相关产品推荐

