Home > Blockchain >  Mongo query filter by nested id
Mongo query filter by nested id

Time:05-23

Hi guys I am starting to use MongoDB with NodeJS. I am not able to generate a query and I really took a look into the documentation and I could not find the answer to my question.

I have a collection like:

{
    _id: "Id",
    username: "name",
    cars: [
        {
            _id: "BMW Car Id"
            name: "BMW",
            colors: [{ _id: "color_red_id", "red"}, { _id: "color_blue_id", "blue"}]
        },
        {
            _id: "Mercedes Car Id"
            name: "Mercedes",
            colors: [{ _id: "color_yellow_id", "yellow"}, { _id: "color_violet_id", "violet"}]
        }
    ]
}

And I want to get the car "BMW" and want to filter the color with the _id (color) "color_red_id" to get something like

{
    _id: "Id",
    username: "name",
    cars: [
        {
            _id: "BMW Car Id"
            name: "BMW",
            colors: [{ _id: "color_red_id", "red"}]
        }
    ]
}

or maybe just get the "color_id" (because is the only thing I really need)

{
    { _id: "color_red_id", "red"}
}

Is that something that we can do?

Thank you and sorry for this, I think, newbie question.

CodePudding user response:

There are several ways to do it, this is a simple one: The $filter filters the array as you wanted and the $unwind divide it into separate documents:

db.collection.aggregate([
  {
    $project: {
      cars: {
        $filter: {
          input: "$cars",
          as: "item",
          cond: {$eq: ["$$item.name", "BMW"]}
        }
      }
    }
  },
  {$unwind: "$cars"},
  {
    $project: {
      cars: {
        $filter: {
          input: "$cars.colors",
          as: "item",
          cond: {$eq: ["$$item._id", "color_red_id"]}
        }
      }
    }
  },
  {$unwind: "$cars"},
  {$replaceRoot: {newRoot: "$cars"}
  }
])

You can see it works on this playground example.

There are many other ways to do it:

  1. $unwind and $match,
  2. $reduce and $filter, 3...

CodePudding user response:

You can use $filter to solve this problem

  • Related