【问题标题】:MongoDB return sub document as an arrayMongoDB将子文档作为数组返回
【发布时间】:2021-12-03 19:56:07
【问题描述】:

我有一个关于猫鼬的问题

const result = await modelProfile.findOne(
    {
      _id: profileId,
    },
    { 'payItems.ACId': 1 }
  );

个人资料样本是

{
    "firstName": "ABC",
    "lastName": "DEF",
    "payItems": [
       {
        "ACId": {
            "$oid": "6168825c5d0edbc0b61615db"
        },
        "balance": 0,
        "rate": 0
    }, {
        "ACId": {
            "$oid": "6168825c5d0edbc0b61615dc"
        },
        "balance": 1,
        "rate": 2
    }]
}

当我运行它时,它会返回以下正确的结果:

{ payItems: 
   [
     { ACId: ObjectId("6168825c5d0edbc0b61615db") },
     { ACId: ObjectId("6168825c5d0edbc0b61615dc") } 
   ] 
}

这是正确的,有什么方法可以让我在 MongoDB 上“不带键”返回类似这样的东西(ID 数组)?

 [  
    ObjectId("6168825c5d0edbc0b61615db"),
    ObjectId("6168825c5d0edbc0b61615dc")
 ]

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    您可以为此使用聚合管道。您可以查看a live demo of this query here

    类似:

    const result = await modelProfile.aggregate([
      {
        "$match": {
          "_id": profileId
        }
      },
      {
        "$group": {
          "_id": null,
          "payItems": {
            "$push": "$payItems.ACId"
          }
        }
      },
      {
        "$project": {
          "_id": 0,
          "payItems": 1
        }
      }
    ])
    

    返回:

    [
      {
        "payItems": [
          [
            ObjectId("6168825c5d0edbc0b61615db"),
            ObjectId("6168825c5d0edbc0b61615dc")
          ]
        ]
      }
    ]
    

    更新

    您可以查看live demo here

    新查询

    db.collection.aggregate([
      {
        "$match": {
          "_id": 1
        }
      },
      {
        "$group": {
          "_id": null,
          "payItems": {
            "$push": "$payItems.ACId"
          }
        }
      },
      {
        "$project": {
          "_id": 0,
          "payItems": 1
        }
      },
      {
        "$unwind": "$payItems"
      }
    ])
    

    新结果

    [
      {
        "payItems": [
          ObjectId("6168825c5d0edbc0b61615db"),
          ObjectId("6168825c5d0edbc0b61615dc")
        ]
      }
    ]
    

    详情

    这意味着你必须这样做:

    const results = await modelProfile.aggregate([
      {
        "$match": {
          "_id": 1
        }
      },
      {
        "$group": {
          "_id": null,
          "payItems": {
            "$push": "$payItems.ACId"
          }
        }
      },
      {
        "$project": {
          "_id": 0,
          "payItems": 1
        }
      },
      {
        "$unwind": "$payItems"
      }
    ]);
    
    results.forEach((result) => {
      // result.payItems has the ids you are looking for
      // If you know you only want the first item in the array
      // just do: 
      // const result = results[0];
      // result.payItems.forEach(item => {...});
    
      result.payItems.forEach((id) => {
        console.log(id);
      });
    })
    

    【讨论】:

    • 谢谢,亲爱的@Matt,有没有办法只接收最后一个嵌套数组,而不是它周围的两个数组?我的意思是结果只有以下? [ ObjectId("6168825c5d0edbc0b61615db"), ObjectId("6168825c5d0edbc0b61615dc") ]
    • 感谢您的宝贵时间@Matt
    • 嘿@MehranIshanian 我用更精致的东西更新了我的答案。
    • 对不起,我一开始误解了你的意思。道歉。
    • 非常欢迎您,@MehranIshanian :) 如果这有助于解决您的问题,请确保将我的答案作为已接受的答案 :) 谢谢。
    猜你喜欢
    • 2020-07-03
    • 2023-04-05
    • 2014-05-28
    • 2020-09-22
    • 2021-06-17
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多