Home > Software engineering >  how to find array element using auto generated id in mongodb
how to find array element using auto generated id in mongodb

Time:02-15

currently, I am struggling with how the MongoDB document system works. I want to fetch array elements with an auto-generated id but how to fetch that specific data that I don't know.

my current schema is

const ItemPricesSchema = new mongoose.Schema({
    _id : {
        type: String
    },
    ItemsPrices: {
        type: [{
            barcode : {
                type: String
            },
            itemName : {
                type: String
            },
            price : {
                type: String
            }
        }]
    }
});

current data is stored in this way

{
    "_id": "[email protected]",
    "ItemsPrices": [
        {
            "barcode": "345345",
            "itemName": "maggie",
            "price": "45",
            "_id": "620a971e11120abbde5f4c3a"
        },
        {
            "barcode": "356345",
            "itemName": "monster",
            "price": "70",
            "_id": "620a971e11120abbde5f4c3b"
        }
    ],
    "__v": 0
}

what I want to achieve is that I want to find array elements through ids

if I want a specific array element with id "620a971e11120abbde5f4c3b" what should I do?? I have tried $unwind , $in, $match...

the result should be like

{
    "_id": "[email protected]",
    "ItemsPrices": [
        {
            "barcode": "356345",
            "itemName": "monster",
            "price": "70",
            "_id": "620a971e11120abbde5f4c3b"
        }
    ],
    "__v": 0
}

CodePudding user response:

You can do an aggregation with $project and apply $filter on the array part. In mongoose you can apply the aggregation query in a more or less similar way https://mongoosejs.com/docs/api/aggregate.html

db.collection.aggregate([
  {
    $project: {
      "ItemsPrices": {
        $filter: {
          input: "$ItemsPrices",
          as: "item",
          cond: {
            $eq: [
              "$$item._id",
              "620a971e11120abbde5f4c3b"
            ]
          }
        }
      },
      "__v": 1  //when projecting 1 means in the final result this field appears
    }
  }
])

more examples

demo

CodePudding user response:

Option 1:

Use $filter in an aggregation query as explained by cmgchess

Option 2:

If you only want one object from array you can use $elemMatch like this:

db.collection.find({
  "ItemsPrices._id": "620a971e11120abbde5f4c3b"
},
{
  "ItemsPrices": {
    "$elemMatch": {
      "_id": "620a971e11120abbde5f4c3b"
    }
  }
})

Example here

But take care, using $elemMatch only the first element is returned. Check this other example where there are two objects with the desired _id but only returns one.

As said before, if you only one (or only exists one) maybe you can use find and $elemMatch to avoid a filter by the entire array. But if can be multiple values use $filter.

  • Related