mongodb - MongoDB - 通过将一个集合中的对象嵌套到另一个集合的对象数组中来聚合两个数组
问题描述
我正在尝试正确编写一个查询,该查询将连接来自两个集合的对象。例如,在一个集合 (A) 中,我有带有字段和用户数组的对象,每个用户对象都有 userDetailsId,我将在加入/合并每个用户和他的每个 userDetails 时使用它集合 B。
集合 A:
{
"_id": "1",
"field1": "value1",
"field2": "value2",
"users": [
{
"userField1": "value3",
"userField2": "value4",
"userDetailsId": "100"
},{
"userField1": "value5",
"userField2": "value6",
"userDetailsId": "200"
}
]
}
集合 B:
{
"_id": "100",
"field1": "value1",
"field2": "value2",
"object1": {
"field3": "value3",
"field4": "value4"
},
"object2": {
"field5": "value5",
"field6": "value6"
}
},
{
"_id": "200",
"field1": "value1",
"field2": "value2",
"object1": {
"field3": "value3",
"field4": "value4"
},
"object2": {
"field5": "value5",
"field6": "value6"
}
}
首选结果:
{
"_id": "1",
"field1": "value1",
"field2": "value2",
"users": [
{
"userField1": "value3",
"userField2": "value4",
"userDetailsId": "100",
"userDetails":{
"_id": "100",
"field1": "value1",
"field2": "value2",
"object1": {
"field3": "value3",
"field4": "value4"
},
"object2": {
"field5": "value5",
"field6": "value6"
}
}
},{
"userField1": "value5",
"userField2": "value6",
"userDetailsId": "200",
"userDetails":{
"_id": "200",
"field1": "value1",
"field2": "value2",
"object1": {
"field3": "value3",
"field4": "value4"
},
"object2": {
"field5": "value5",
"field6": "value6"
}
}
}
]
}
我写的查询之一,但没有得到首选的结果:
db.collectiona.aggregate([{$match: {'_id':1}},{$lookup:{from:"collectionb", localField: "users.userdetailsid", foreignField: "_id", as:"userdetails"}}
如果我运行它,我将合并这两个集合,并将集合 B 中所有匹配的 userdetails 对象作为 userdetails 数组包含在结果中。
由于我的目标是将用户及其用户详细信息合并到用户对象中,因此我尝试将其设置为:“users.userdetails”,但这将用用户详细信息数据替换用户(还没有找到一种可能的方法将 upsert 设置为 true 并添加整个匹配 userdetailsid 时用户中的 userdetails 对象)。
之后,我尝试管道聚合的结果,并尝试将 userdetails 放入带有查询的用户对象中
db.collectiona.aggregate([{$match: {'_id':1}},{$lookup:{from:"collectionb", localField: "users.userdetailsid", foreignField: "_id", as:"userdetails"},
{"$addFields":{
"user.userdetails":{
"$map":{
"input": "$shifts",
"in":{
"$mergeObjects":["$$this",{"$arrayElemAt":["$collectionb",{"$indexOfArray":["$collectionb.id","$$this.userdetailsid"]}]}]
}
}
}
}}
}
但这也不好。
你有什么想法我怎么能正确地编写查询来获得这种结果?
解决方案
您需要首先$unwind
将users
数组与正确的数组匹配,然后userDetailsId
再将用户回滚到数组中$group
$push
db.collectiona.aggregate([
{ "$match": { "_id": 1 }},
{ "$unwind": "$users" },
{ "$lookup": {
"from": "collectionb",
"localField": "users.userDetailsId",
"foreignField": "_id",
"as": "users.userDetails"
}},
{ "$unwind": "$users.userDetails" },
{ "$group": {
"_id": "$_id",
"field1": { "$first": "field1" }
"field2": { "$first": "field2" }
"users": { "$push": "users" }
}}
])
推荐阅读
- javascript - 如何在 JavaScript 中真实地为模拟事件生成时间戳
- c# - 使用 OpenXML 在 word 中创建动态项目的编号列表
- java - Java/Processing,查找文件夹中的文件数量
- node.js - 在 module.exports 内部进行异步函数调用
- java - 在环境模式下更频繁地更新不起作用 - Android Wear / WearOS
- java - 使用 jdbcTemplate 执行不带参数的 SQL 语句时遇到“java.sql.SQLException: Invalid column index”。
- python - 创建两个numpy.ndarray的字典?
- laravel - Vue.js + Laravel5.7 'Hello World' 测试不起作用
- python - 返回元组列表时字符串索引超出范围
- excel - [@column] 和 [column] 之间的 Excel 表格参考差异