Home > OS >  MongoDB return sub document as an array
MongoDB return sub document as an array

Time:10-19

I have a query on mongoose

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

profile sample is

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

when I ran it, it returns the following results that is correct:

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

That is correct, is there any way that I can MongoDB that I would like to return it "without keys" something like this (array of Ids)?

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

CodePudding user response:

You can use the aggregation pipeline for this. You can check out a live demo of this query here

Something like:

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

Which returns:

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

UPDATE

You can check out a live demo here

New Query

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

New Results

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

Details

This means you will have to do something like this:

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);
  });
})
  • Related