I try to use mongoose aggregate and $lookup in array of the model, but it just works for the first index of array. I have user model and product model:
Schema:
// user schema
const UserSchema = new mongoose.Schema(
{
name: { type: String, default: "", required: true},
password: { type: String, default: "" },
},
{
toJSON : {
virtuals : true
},
timestamps: true,
}
);
module.exports = {
UserModel: mongoose.model("user", UserSchema),
};
// products schema
const buyerSchema = new mongoose.Schema(
{
user: { type: mongoose.Types.ObjectId, ref: "user", required: true },
count: { type: Number, default: 1 },
},
{
toJSON: {
virtuals: true,
},
timestamps: true,
}
);
const productSchema = new mongoose.Schema(
{
buyers: { type: [buyerSchema], default: "", required: true},
name: { type: String, default: "", ref: "user" },
price : { type: Number, required: true} },
},
{
toJSON : {
virtuals : true
},
timestamps: true,
}
);
module.exports = {
ProductModel: mongoose.model("product", productSchema),
};
code in pictures:
Aggregate code:
const products = await ProductModel.aggregate([
{
$match: {},
},
{
$lookup: {
from: "users",
localField: "buyers.user",
foreignField: "_id",
as: "buyers.user",
},
},
]);
but in this way, it just looks for the first item in array buyers and then replaces user id with that
Output without aggregate (just .find({}) )
{
"status": 200,
"products": [
{
"_id": "12b9e10912b6d307f811f2cb",
"name": "product 1",
"price": 10000,
"buyers": [
{
"user": "61b9d51423b6d107f811f2a1",
"count": 3,
"_id": "62bad18114f376b0fe109709",
"updatedAt": "2022-06-28T10:29:21.943Z",
"createdAt": "2022-06-28T10:29:21.943Z"
},
{
"user": "61b9d51423b6d107f811f2a1",
"count": 2,
"_id": "62bad118114f176b1fe109109",
"updatedAt": "2022-06-28T10:29:21.943Z",
"createdAt": "2022-06-28T10:29:21.943Z"
},
{
"user": "61b9d51423b6d107f811f2a1",
"count": 1,
"_id": "621ad18114f376b0f1097091",
"updatedAt": "2022-06-28T10:29:21.943Z",
"createdAt": "2022-06-28T10:29:21.943Z"
}
],
"__v": 0
},
{
"_id": "12b9e10911b6d307f811f2cb",
"name": "product 2",
"price": 1500,
"buyers": [
{
"user": "61b9d51423b6d107f811f2a1",
"count": 1,
"_id": "62bad18114f376b0fe109709",
"updatedAt": "2022-05-28T10:29:21.943Z",
"createdAt": "2022-05-28T10:29:21.943Z"
},
{
"user": "61b9d51423b6d107f811f2a1",
"count": 10,
"_id": "621ad18114f371b0f1097091",
"updatedAt": "2022-03-28T10:29:21.943Z",
"createdAt": "2022-03-28T10:29:21.943Z"
}
],
"__v": 0
}
]
}
Output with aggregate:
{
"statusCode": 200,
"success": true,
"posts": [
{
"_id": "12b9e10912b6d307f811f2cb",
"name": "product 1",
"price": 10000,
"products": {
"buyers": [
{
"_id": "61b9d51423b6d107f811f2a1",
"name": "testing",
"password":"$2b$10$zXQaqsf.4FCmJvuj6DFSruSFSlxnds7a7VoLaVktsBwuIPi9HmfSG",
"createdAt": "2022-03-27T16:04:52.366Z",
"updatedAt": "2022-03-27T19:14:17.064Z",
"__v": 0
}
]
},
"updatedAt": "2022-06-28T10:29:21.943Z",
"createdAt": "2022-06-28T10:29:21.943Z",
"__v": 0
},
{
"_id": "12b9e10911b6d307f811f2cb",
"name": "product 2",
"price": 1500,
"buyers": [
{
"_id": "61b9d51423b6d107f811f2a1",
"name": "testing",
"password":"$2b$10$zXQaqsf.4FCmJvuj6DFSruSFSlxnds7a7VoLaVktsBwuIPi9HmfSG",
"createdAt": "2022-03-27T16:04:52.366Z",
"updatedAt": "2022-03-27T19:14:17.064Z",
"__v": 0
}
],
"__v": 0
}
]
}
CodePudding user response:
You can use the $map
expr to loop through buyers array and inside use the $lookup
expr.