Search code examples
reactjsmongodbmongoosenext.js

.populate() method is not working in mongodb


I'm using Nextjs to create an ecommerce application. I have a reviews array made of objects, which contains a property reviewBy.

I want to populate this reviewBy property like this:

{
  "_id": {
    "$oid": "62c4711c062128444ad591a1"
  },
  "name": "Allover Plants Print Square Neck Knot Front Dress",
  "description": "Allover Plants Print Square Neck Knot Front Dress",
  "brand": "Boho",
  "slug": "Allover-Plants-Print-Square-Neck-Knot-Front-Dress",
  "category": {
    "$oid": "62c46ff0062128444ad59193"
  },
  "subCategories": [
    {
      "$oid": "62c46ffd062128444ad59199"
    }
  ],
  "details": [
    {
      "name": "Style",
      "value": "Boho",
      "_id": {
        "$oid": "62c4711c062128444ad591a2"
      }
    },
    {
      "name": "Pattern Type",
      "value": "Plants, All Over Print",
      "_id": {
        "$oid": "62c4711c062128444ad591a3"
      }
    },
    {
      "name": "Details",
      "value": "Knot",
      "_id": {
        "$oid": "62c4711c062128444ad591a4"
      }
    },
    {
      "name": "Type",
      "value": "A Line",
      "_id": {
        "$oid": "62c4711c062128444ad591a5"
      }
    },
    {
      "name": "Neckline",
      "value": "Square Neck",
      "_id": {
        "$oid": "62c4711c062128444ad591a6"
      }
    },
    {
      "name": "Sleeve Length",
      "value": "Short Sleeve",
      "_id": {
        "$oid": "62c4711c062128444ad591a7"
      }
    },
    {
      "name": "Sleeve Type",
      "value": "Puff Sleeve",
      "_id": {
        "$oid": "62c4711c062128444ad591a8"
      }
    },
    {
      "name": "Waist Line",
      "value": "High Waist",
      "_id": {
        "$oid": "62c4711c062128444ad591a9"
      }
    },
    {
      "name": "Hem Shaped",
      "value": "Flared",
      "_id": {
        "$oid": "62c4711c062128444ad591aa"
      }
    },
    {
      "name": "Length",
      "value": "Long",
      "_id": {
        "$oid": "62c4711c062128444ad591ab"
      }
    },
    {
      "name": "Fit Type",
      "value": "Regular Fit",
      "_id": {
        "$oid": "62c4711c062128444ad591ac"
      }
    },
    {
      "name": "Fabric",
      "value": "Non-Stretch",
      "_id": {
        "$oid": "62c4711c062128444ad591ad"
      }
    },
    {
      "name": "Material",
      "value": "Polyester",
      "_id": {
        "$oid": "62c4711c062128444ad591ae"
      }
    }
  ],
  "questions": [],
  "subProducts": [
    {
      "sku": "sw2206138988536738",
      "discount": 0,
      "images": [
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041164/products/j9h8giisorvqwnxgy6lx.webp",
          "public_url": "products/j9h8giisorvqwnxgy6lx"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041168/products/tpwwbcdjxdzk1qok7jqu.webp",
          "public_url": "products/tpwwbcdjxdzk1qok7jqu"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041171/products/lopvo38miankt6j0usaz.webp",
          "public_url": "products/lopvo38miankt6j0usaz"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041176/products/mjrdih9alzizp5lkb0ty.webp",
          "public_url": "products/mjrdih9alzizp5lkb0ty"
        }
      ],
      "description_images": [],
      "color": {
        "color": "#ecd297",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041179/products/ac3homl0yeimydql5rq4.webp"
      },
      "sizes": [
        {
          "size": "S",
          "qty": 15,
          "price": 17,
          "_id": {
            "$oid": "62c4711c062128444ad591b0"
          }
        },
        {
          "size": "M",
          "qty": 1414,
          "price": 19,
          "_id": {
            "$oid": "62c4711c062128444ad591b1"
          }
        },
        {
          "size": "L",
          "qty": 0,
          "price": 21,
          "_id": {
            "$oid": "62c4711c062128444ad591b2"
          }
        },
        {
          "size": "XL",
          "qty": 1423,
          "price": 28,
          "_id": {
            "$oid": "62c4711c062128444ad591b3"
          }
        }
      ],
      "_id": {
        "$oid": "62c4711c062128444ad591af"
      }
    },
    {
      "images": [
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045381/products/qbwsyo2xg26zxyygtuzs.webp",
          "public_url": "products/qbwsyo2xg26zxyygtuzs"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045385/products/fxuhya9s4usojgdfune9.webp",
          "public_url": "products/fxuhya9s4usojgdfune9"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045389/products/acscvdlnkyt8r7kifsw5.webp",
          "public_url": "products/acscvdlnkyt8r7kifsw5"
        },
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045392/products/suok4nz4ocdmegkzmqvs.webp",
          "public_url": "products/suok4nz4ocdmegkzmqvs"
        }
      ],
      "sku": "vc22142578988545614",
      "description_images": [],
      "color": {
        "color": "#dac4ac",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045396/products/ouh3i2klgrmwluexm3q9.webp"
      },
      "sizes": [
        {
          "size": "M",
          "qty": 1456,
          "price": 15,
          "_id": {
            "$oid": "62c481967d2df7b52aa1f9e3"
          }
        },
        {
          "size": "L",
          "qty": 1700,
          "price": 21,
          "_id": {
            "$oid": "62c481967d2df7b52aa1f9e4"
          }
        }
      ],
      "discount": 10,
      "_id": {
        "$oid": "62c481967d2df7b52aa1f9e2"
      }
    }
  ],
  "createdAt": {
    "$date": "2022-07-05T17:13:00.324Z"
  },
  "updatedAt": {
    "$date": "2022-07-09T09:44:46.823Z"
  },
  "__v": 17,
  "numReviews": 5,
  "rating": 3.5,
  "refundPolicy": "30 days",
  "reviews": [
    {
      "reviewBy": {
        "$oid": "62b33178fbcc6f0282db0606"
      },
      "rating": 1,
      "review": "aaaaaaaaaaaaaaa",
      "size": "S",
      "style": {
        "color": "#dac4ac",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045396/products/ouh3i2klgrmwluexm3q9.webp"
      },
      "fit": "Small",
      "images": [
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657145489/reviews/whcchkvkbd4dypptoccx.webp",
          "public_url": "reviews/whcchkvkbd4dypptoccx"
        }
      ],
      "_id": {
        "$oid": "62c6089247a21fb57bb8b234"
      },
      "createdAt": {
        "$date": "2022-07-06T22:11:30.149Z"
      },
      "updatedAt": {
        "$date": "2022-07-09T09:44:46.559Z"
      }
    },
    {
      "reviewBy": {
        "$oid": "62c69fc002820c409dcce9ea"
      },
      "rating": 4,
      "review": "i like it  a lot but a bit large for me for size L",
      "size": "L",
      "style": {
        "color": "#dac4ac",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045396/products/ouh3i2klgrmwluexm3q9.webp"
      },
      "fit": "Large",
      "images": [],
      "_id": {
        "$oid": "62c6a03702820c409dcce9f2"
      },
      "createdAt": {
        "$date": "2022-07-07T08:58:31.646Z"
      },
      "updatedAt": {
        "$date": "2022-07-07T08:58:31.646Z"
      }
    },
    {
      "reviewBy": {
        "$oid": "62a22b5cd0e120974f5c866e"
      },
      "rating": 5,
      "review": "amaaaaaaaaaaaaaaaaaaaaaaazing",
      "size": "L",
      "style": {
        "color": "#dac4ac",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657045396/products/ouh3i2klgrmwluexm3q9.webp"
      },
      "fit": "Large",
      "images": [
        {
          "url": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657189685/reviews/i6wmqtwnjcolkguit6qi.webp",
          "public_url": "reviews/i6wmqtwnjcolkguit6qi"
        }
      ],
      "_id": {
        "$oid": "62c6b13402820c409dccea08"
      },
      "createdAt": {
        "$date": "2022-07-07T10:11:00.304Z"
      },
      "updatedAt": {
        "$date": "2022-07-07T10:28:07.389Z"
      }
    },
    {
      "reviewBy": {
        "$oid": "62a22d98d0e120974f5c8671"
      },
      "rating": 2.5,
      "review": "aaaaaaaa",
      "size": "S",
      "style": {
        "color": "#ecd297",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041179/products/ac3homl0yeimydql5rq4.webp"
      },
      "fit": "True to size",
      "images": [],
      "_id": {
        "$oid": "62c6d15802820c409dccea3d"
      },
      "createdAt": {
        "$date": "2022-07-07T12:28:08.226Z"
      },
      "updatedAt": {
        "$date": "2022-07-07T12:30:52.277Z"
      }
    },
    {
      "reviewBy": {
        "$oid": "62a2281cd0e120974f5c866c"
      },
      "rating": 5,
      "review": "bbbbbbbbbbbbbb",
      "size": "S",
      "style": {
        "color": "#ecd297",
        "image": "https://res.cloudinary.com/dmhcnhtng/image/upload/v1657041179/products/ac3homl0yeimydql5rq4.webp"
      },
      "fit": "True to size",
      "images": [],
      "_id": {
        "$oid": "62c6d29602820c409dccea5e"
      },
      "createdAt": {
        "$date": "2022-07-07T12:33:26.719Z"
      },
      "updatedAt": {
        "$date": "2022-07-07T12:33:26.719Z"
      }
    }
  ],
  "shipping": "2"
}

so, i written code like this:

  let product: any = await Product.findOne({ slug })
    .populate({ path: "category", model: Category })
    .populate({ path: "subCategories._id", model: SubCategory })
    .populate({ path: "reviews.reviewBy", model: User })
    .lean();

So as per my instructor, he told to use "reviews.reviewBy". but it was throwing me null in that place.

Please help me. because iam newbie here. If you find this as stupid question please just ignore it. it's beginner mistake. :)


Solution

  • Make sure you have a reference to each subdocument you want to populate in your Product schema as described in the docs. For example, your schema should resemble:

    const productSchema = new mongoose.Schema({
       //...
       //...
       slug: String,
       category: {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Category' //< Make sure you have a reference to Category
       },
       subCategories:[{
          type: mongoose.Schema.Types.ObjectId,
          ref: 'SubCategory' //< Make sure you have a reference to SubCategory
       }],
       //...
       //...
       reviews:[{
          reviewBy:{
             type: mongoose.Schema.Types.ObjectId,
             ref: 'User' //< Make sure you have a reference to User
          },
          //...
          //...
       }]
       //...
       //...
    });
    

    This will make your populate methods work correctly like so:

    const product = await Product.findOne({ slug })
       .populate({ path: "category", model: Category })
       .populate({ path: "subCategories", model: SubCategory })
       .populate({ path: "reviews.reviewBy", model: User })
       .lean();