【问题标题】:Joining mongodb collection based on condition [duplicate]根据条件加入mongodb集合[重复]
【发布时间】:2020-03-30 09:14:48
【问题描述】:

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

我想加入 'order' 和 'order-status' 表以获取所有分配给 '123' 且状态为 'ready' 的订单

订单

{
 "_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"
}

我想加入 'order' 和 'order-status' 表以获取所有分配给 '123' 且状态为 'ready' 的订单

期待最终结果

[
{
 "_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'
  }
]);

【问题讨论】:

  • 你能给受让人提供样本数据吗?
  • @SuleymanSah 我有疑问,我是否需要将受理人放入订单状态表中以获得数据库正确参考?即“受让人”:“123”
  • 能否提供样本数据以便我们检查?
  • @SuleymanSah 更新受让人收藏
  • 嗯,其实不需要加入assignee,我已经回复了,可以查一下吗?

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


【解决方案1】:

首先你需要使用match来过滤"assignee": "123",然后你需要查找order-status,匹配"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

【讨论】:

    【解决方案2】:

    我会使用以下管道:

    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"
            }
        }
    ]);
    

    【讨论】:

      猜你喜欢
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2020-05-13
      • 2017-08-29
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      相关资源
      最近更新 更多