You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:36:22