根据条件加入mongodb集合

时间:2019-12-05 12:25:58

标签: node.js mongodb join mongoose aggregation-framework

我在MongoDB中有两个集合,并希望根据某些条件加入这两个集合。

我想加入“订单”和“订单状态”表以获取所有分配给“ 123”且状态为“就绪”的订单

订单

{
 "_id":"1",
 "name": "Fridge",
 "assignee": "123"
},
{
 "_id":"2",
 "name": "TV",
 "assignee": "567"
},
{
 "_id":"3",
 "name": "Music system",
 "assignee": "123"
}

订单状态

{
 "_id":"1",
 "status": "ready",
 "orderId": "1"
},
{
 "_id":"2",
 "status": "cancelled",
 "orderId": "2"
},
{
 "_id":"3",
 "status": "cancelled",
 "orderId": "3"
}

受让人

{
 "_id":"123",
 "name": "Jak"
}
{
 "_id":"567",
 "name": "Mac"
}

我想加入“订单”和“订单状态”表以获取所有分配给“ 123”且状态为“就绪”的订单

期望最终结果为

[
{
 "_id":"1",
 "name": "Fridge",
 "assignee": "123",
 "status": {
  "_id":"1",
 "status": "ready",
 "orderId": "1"
 }
}
]

尝试以下操作,但如何使用查找方法检查另一个表中的订单状态

const resultObject = orders.aggregate([
  { $match : {assignee: Objectid('123')} },
  {
    $lookup: {
      from: 'user-status',
      localField: 'assignee',
      foreignField : '_id',
      as : 'assignee'
    }
  },
  {
    $unwind: '$assignee'
  }
]);

2 个答案:

答案 0 :(得分:1)

首先,您需要使用match来按"assignee": "123"进行过滤,然后您需要查找订单状态,匹配"orderStatus.status": "ready"

const resultObject = orders.aggregate([
  {
    $match: {
      assignee: "123"
    }
  },
  {
    $lookup: {
      from: "order-status",
      localField: "_id",
      foreignField: "orderId",
      as: "statuses"
    }
  },
  {
    $match: {
      "statuses.status": "ready"
    }
  },
  {
    $project: {
      id: "_id",
      name: "$name",
      assignee: "$assignee",
      status: {
        $arrayElemAt: ["$statuses", 0]
      }
    }
  }
]);

这将给出如下结果:

[
  {
    "_id": "1",
    "assignee": "123",
    "name": "Fridge",
    "status": {
      "_id": "1",
      "orderId": "1",
      "status": "ready"
    }
  }
]

Playground

答案 1 :(得分:0)

我将使用以下管道:

const resultObject = orders.aggregate([
    {
        $match: {
            assignee: Objectid('123')
        }
    },
    {
        $lookup:
            {
                from: "order-status",
                let: {order_id: "$_id"},
                pipeline: [
                    {
                        $match:
                            {
                                $expr:
                                    {
                                        $and:
                                            [
                                                {$eq: ["$orderId", "$$order_id"]},
                                                {$eq: ["$status", "ready"]}
                                            ]
                                    }
                            }
                    }
                ],
                as: "stock"
            }
    },
    {
        $unwind: "$stock"
    },
    // now we get the assignee info.
    {
        $lookup: {
            from: 'user-status',
            localField: 'assignee',
            foreignField: '_id',
            as: 'assignee'
        }
    },
    {
        $unwind: '$assignee'
    },
    //finaly create the required structure.
    {
        $project: {
            name: "$assignee.name",
            assignee: "$assignee._id",
            status: "$stock.0"
        }
    }
]);