【问题标题】:Aggregation of two collections in MongoDBMongoDB中两个集合的聚合
【发布时间】:2017-07-13 06:44:00
【问题描述】:

我有两个集合,我正在尝试对其进行某种查找。我不是 100% 确定如何处理它。

集合 1:员工

{
 "data": [
  {
     "full name": "Keith Richards",
     "age": 21,
     "userName": "keith1@keith.com",
     "employeeDetails": {
        "id": 102522
    }
  },
  {
    "full name": "Jim Morrison",
     "age": 27,
     "userName": "jim@jim.com",
     "employeeDetails": {
        "id": 135522
    }
  }
 ]
}

收藏 2:参赛作品

{
 "data": [
  {
     "dateCreated": "02-04-2016",
     "billable": true,
     "minutes": 150,
     "employeeId": {
        "id": 102522
        }
  },
  {
     "dateCreated": "03-04-2016",
     "billable": true,
     "minutes": 250,
     "employeeId": {
        "id": 102522
   }
  },
  {
     "dateCreated": "04-04-2016",
     "billable": true,
     "minutes": 20,
     "employeeId": {
        "id": 135522
   }
  }
]
}

您可以看到 Employees 集合中的 employeeDetails.idEntries 中的 employeeId.id 匹配> 收藏。

我正在尝试进行查找,以便将条目中的 id 与员工中的用户名匹配,这样我就可以将名称与条目匹配,所需的结果如下:

{
 "data": [
  {
     "full name": "Keith Richards",
     "dateCreated": "02-04-2016",
     "minutes": 150,
     "employeeId": {
        "id": 102522
        }
  },
  {
     "full name": "Keith Richards",
     "dateCreated": "03-04-2016",
     "minutes": 250,
     "employeeId": {
        "id": 102522
        }
  },
  {
     "full name": "Jim Morrison",
     "dateCreated": "04-04-2016",
     "minutes": 20,
     "employeeId": {
        "id": 135522
  }
 }
]
}

这将允许我得到一个组/总和的最终结果:

  • 全名:基思·理查兹
  • 分钟:400
  • 全名:吉姆·莫里森
  • 分钟:20

我尝试了一堆,唯一接近工作的是以下:

db.getCollection('entries')
.aggregate(
  [
    {
      "$lookup": {
        "from": "employees", 
        "localField": "trafficEmployeeId.id", 
        "foreignField": "employeeDetails.id", 
        "as": "employees_loaded"
      }
    }
  ]
);

这基本上给了我一个包含两个不同数组的集合。

谁能给我建议/解决方案,以最佳方式实现我想要实现的目标?我选择了 MongoDB,因为输入严重依赖 JSON 输入。

【问题讨论】:

    标签: json mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您需要将data 数组本身的内容包含为集合项。例如,您的 employees 集合应如下所示:

    {
        "full name": "Keith Richards",
        "age": 21,
        "userName": "keith1@keith.com",
        "employeeDetails": {
            "id": 102522
        }
    }, {
        "full name": "Jim Morrison",
        "age": 27,
        "userName": "jim@jim.com",
        "employeeDetails": {
            "id": 135522
        }
    }
    

    这样你就可以像这样轻松$lookup

    db.entries.aggregate(
        [
            { $unwind: "$data" }, {
                $lookup: {
                    "from": "employees",
                    "localField": "data.employeeId.id",
                    "foreignField": "employeeDetails.id",
                    "as": "employees_loaded"
                }
            }, {
                $unwind: "$employees_loaded"
            }, {
                $group: {
                    "_id": 1,
                    "data": {
                        $push: {
                            "full name": "$employees_loaded.full name",
                            "dateCreated": "$data.dateCreated",
                            "minutes": "$data.minutes",
                            "employeeId": "$data.employeeId"
                        }
                    }
                }
            }
        ]
    );
    

    $unwind 用于删除从$lookup 生成的employees_loaded 数组。 $group 阶段用于获取您想要保留的字段并将$push 它们放入一个名为data 的数组中

    【讨论】:

    • 非常感谢! - 这让我更接近了。问题是,它给了我 4 个数组,全名、dateCreated、分钟和employeeId。它们只是列出,但不匹配。我需要将以上内容包装在“匹配”或函数中吗?示例链接:i.imgsafe.org/e2ff25c59c.png
    • 您要匹配特定的用户名或员工身份吗?
    • 两个集合都有employeeId,但只有Employee集合有用户名。我希望能够将 Employee 中的 userName 与 Entries 集合中的 employeeId 匹配。这样,我可以输出一个完整列表(分钟)并让每个显示用户名。
    • 在您的条目集合中,您是否像在员工集合中一样将数据数组项移动到集合本身?
    • 不,根据文章顶部的 JSON 示例,它们位于不同的集合中。
    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 2020-01-31
    • 2023-03-28
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 2020-04-25
    相关资源
    最近更新 更多