KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20088

Not able to receive expected result in mongodb between collections

I'm trying to get a product list with logged user wishlist in the product list itself. I'm trying $lookup but not getting the expected result.

Product Document:

[
{
    "_id" : ObjectId("6044351794bee8b6e0fce48f"),
    "sku" : "P003474",
    "name" : "Kitchen Wash"
},
{
    "_id" : ObjectId("6085584c42ad3c58c5dbc6b7"),
    "sku" : "TS0012",
    "name" : "T-shirt"
},
{
    "_id" : ObjectId("608d20a90e629fcc0d3a93e1"),
    "sku" : "Apple1101",
    "name" : "Green Apple"
}
]

Wishlist Document:

wishlist:

[
{
    "_id" : ObjectId("608d8af12b7556c445f5cd87"),
    "product" : ObjectId("6044351794bee8b6e0fce48f"),
    "user" : ObjectId("601fb31a60e0a024143e6ea3"),
    "isLiked" : false
},
{
    "_id" : ObjectId("608d8bad2b7556c445f5cd88"),
    "product" : ObjectId("6085584c42ad3c58c5dbc6b7"),
    "user" : ObjectId("601fb31a60e0a024143e6ea3"),
    "isLiked" : true
}
]

Expected Result:

Expected output:

[
{
    "_id" : ObjectId("6044351794bee8b6e0fce48f"),
    "sku" : "P003474",
    "name" : "Kitchen Wash",
    "isLiked": false
},
{
    "_id" : ObjectId("6085584c42ad3c58c5dbc6b7"),
    "sku" : "TS0012",
    "name" : "T-shirt",
    "isLiked": true
},
{
    "_id" : ObjectId("608d20a90e629fcc0d3a93e1"),
    "sku" : "Apple1101",
    "name" : "Green Apple"
}
]

The query I'm trying:

db.getCollection('products').aggregate([
  {
    $lookup: {
      from: "wishlists",
      localField: "_id",
      foreignField: "product",
      as: "product"
    }
  },
  {
    $unwind:"$product"
  }
])

Not able to get the above-declared result

Upvotes: 1

Views: 31

Answers (1)

turivishal
turivishal

Reputation: 36104

  • $unwind causing the issues, first problem is it will remove document when product lookup result empty/[] if you don't specify preserveNullAndEmptyArrays : true, see working behaviour in playground
  • use $lookup with pipeline and match product id and user id condition
  • i have changed as name to isLiked in $lookup
  • $addFields to add isLiked parameter it its present, $arrayElemAt to get isLiked element from first element
db.getCollection('products').aggregate([
  {
    $lookup: {
      from: "wishlists",
      let: { product: "$_id" },
      pipeline: [
        {
          $match: {
            $and: [
              { $expr: { $eq: ["$$product", "$product"] } },
              { user: ObjectId("601fb31a60e0a024143e6ea3") }
            ]
          }
        }
      ],
      as: "isLiked"
    }
  },
  {
    $addFields: {
      isLiked: { $arrayElemAt: ["$isLiked.isLiked", 0] }
    }
  }
])

Playground

Upvotes: 1

Related Questions