MongoDB $lookup on one document's array of object

感情迁移 提交于 2021-02-08 03:31:18

问题


I have searched online but could not find any match my case. Here is the situation.

I am using aggregate to combine one collection and one document which is from another collection together

restaurants.aggregate([
  {
    $match: {
      _id: {
        $in: idList
      }
    }
  },
  {
    $lookup: {
      from: "tags",
      localField: "details.restaurantType",
      foreignField: "details.restaurantType._id",
      as: "types"
    }
  },
  {
    $project: {
      restaurantName: "$details.restaurantName",
      restaurantType: "$details.restaurantType",
      type: {
        $filter: {
          input: "$types",
          as: "type",
          cond: {
            $eq: ["$$type._id", "$details.restaurantType"]
          }
        }
      },
      currency: "$details.currency",
      costPerPax: "$details.costPerPax"
    }
  }
]);

current result

The 'type' field in my current result is [], I need a matched value instead

[
    {
        "id": "5c20c7a0036dda80a8baabcc",
        "restaurantName": "Villagio Restaurant Sutera Mall",
        "type": [],
        "currency": "RM",
        "costPerPax": 22,
    },
    {
        "id": "5c20ceb07715216d3c217b7a",
        "restaurantName": "Thai Food Thai Now Sutera Mall",
        "type": [],
        "currency": "RM",
        "costPerPax": 16,
    }
]

expected result

I need the 'type' fields has match tag name from another collection like this

[
    {
        "id": "5c20c7a0036dda80a8baabcc",
        "restaurantName": "Villagio Restaurant Sutera Mall",
        "type": "Western",
        "currency": "RM",
        "costPerPax": 22,
    },
    {
        "id": "5c20ceb07715216d3c217b7a",
        "restaurantName": "Thai Food Thai Now Sutera Mall",
        "type": "Thai",
        "currency": "RM",
        "costPerPax": 16,
    }
]

Extra Information

two document from restaurants collection

    {
        "details": {
            "restaurantName": "Villagio Restaurant Sutera Mall",
            "restaurantType": "5c01fb57497a896d50f498a8"
        },
        "_id": "5c20c7a0036dda80a8baabcc",
        "status": "OP",
        "__v": 0
    },
    {
        "details": {
            "restaurantName": "Kingshahi Japanese Shop",
            "restaurantType": "5c01fb57497a896d50f49879"
        },
        "_id": "5c20cb4fb7e75180480690c2",
        "status": "OP",
        "__v": 0
    } 

One document from tag collection

        {
            "_id": "5c01fb57497a896d50f49876",
            "details": {
                "restaurantTypeId": "5c01fb57497a896d50f49877",
                "restaurantTypes": [
                    {
                        "_id": "5c01fb57497a896d50f49879",
                        "name": "Asian",
                        "counter": 1
                    },
                    {
                        "_id": "5c01fb57497a896d50f4987a",
                        "name": "Bakery",
                        "counter": 0
                    }
                ]
            }
        }

回答1:


You can use below optimised aggregation pipeline

db.restaurants.aggregate([
  { "$lookup": {
    "from": "tags",
    "let": { "restaurantType": "$details.restaurantType" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": ["$$restaurantType", "$details.restaurantTypes._id"] }
      }},
      { "$unwind": "$details.restaurantTypes" },
      { "$match": {
        "$expr": { "$eq": ["$details.restaurantTypes._id", "$$restaurantType"] }
      }}
    ],
    "as": "types"
  }},
  { "$project": {
    "restaurantName": "$details.restaurantName",
    "restaurantType": "$details.restaurantType",
    "type": { "$arrayElemAt": ["$types.details.restaurantTypes.name", 0] },
    "currency": "$details.currency",
    "costPerPax": "$details.costPerPax"
  }}
])


来源:https://stackoverflow.com/questions/53966763/mongodb-lookup-on-one-documents-array-of-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!