Home > Software engineering >  mongoose Aggregate, $lookup array in model
mongoose Aggregate, $lookup array in model

Time:06-30

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:

enter image description here

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.

  • Related