如何在数组的字段中进行 $lookup 并在同一查询中添加外部 table 的内容?
How to do $lookup in an array's field and add the foreign table's content in the same query?
我正在尝试进行查询,其中我有一个 db_task
查询,其中包含任务 ID 和分配给它的用户。我必须获取 db_user 集合中存在的用户详细信息,并将传入的详细信息添加到同一文档中。
db_task
{
"_id" : ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users" : [
{
"user_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"is_finished" : false
},
{
"user_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"is_finished" : false
}
]
}
用户字段分配了该任务的用户,我想对 db_user
查询进行查找,这将使我获得同一嵌入式文档中的详细信息。
db_user
{
"_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"first_name" : "Harry",
"last_name" : "Paul"
},
{
"_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"first_name" : "Aaron",
"last_name" : "Potter"
}
我尝试使用 "users.user_id" 在 db_user table 上进行 $lookup,但这会为我获取一个新字段,然后我尝试将这些数组与“$concatArrays”连接起来但是结果还是不是我想的那样。
我想以类似这样的格式获得输出
db_task
{
"_id" : ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users" : [
{
"user_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"is_finished" : false,
"user_info":{
"first_name" : "Harry",
"last_name" : "Paul"
}
},
{
"user_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"is_finished" : false,
"user_info":{
"first_name" : "Aaron",
"last_name" : "Potter"
}
}
]
}
它适合你。
db_task.aggregate([
{
$match: { '_id': ObjectId("5d8b522d0cf2579c57bc8ce0") }
},
{
$unwind: '$users'
},
{
$lookup: {
from: 'db_user',
localField: 'users.user_id',
foreignField: '_id',
as: 'user_info'
}
},
{
$project: {
$users: {
user_id: 1,
is_finished: 1,
user_info:'$user_info',
}
}
},
{
$group: {
_id: '$_id',
users: {
$push: '$users'
},
}
},
])
几乎与 vishal pankhaniya 解决方案相同,但我们从内部文档
中排除了 user_info._id
db.db_task.aggregate([
{
$unwind: "$users"
},
{
$lookup: {
from: "db_user",
localField: "users.user_id",
foreignField: "_id",
as: "user_info"
}
},
{
$project: {
users: {
user_id: 1,
is_finished: 1,
user_info: "$user_info"
}
}
},
{
$group: {
_id: "$_id",
users: {
$push: "$users"
}
}
},
{
$project: {
"users.user_info._id": 0
}
}
])
结果
[
{
"_id": ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users": [
{
"is_finished": false,
"user_id": ObjectId("5d8b522d0cf2579e27bc8ce3"),
"user_info": [
{
"first_name": "Harry",
"last_name": "Paul"
}
]
},
{
"is_finished": false,
"user_id": ObjectId("5d6f6d25e079b9fb7d858236"),
"user_info": [
{
"first_name": "Aaron",
"last_name": "Potter"
}
]
}
]
}
]
虽然他们在工作,但所提供的解决方案,包括放松和分组,在资源方面可能是昂贵的。
这里有一个更好的解决方案,只需要两个阶段:
db.db_task.aggregate([
{
$lookup: {
from: "db_user",
localField: "users.user_id",
foreignField: "_id",
as: "usersInfos"
}
},
{
$project: {
users: {
$map: {
input: "$usersInfos",
as: "ui",
in: {
$mergeObjects: [
"$$ui",
{
$arrayElemAt: [
{
$filter: {
input: "$users",
as: "users",
cond: {
$eq: [
"$$users.user_id",
"$$ui._id"
]
}
}
},
0
]
}
]
}
}
}
}
}
])
会输出
[
{
"_id": ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users": [
{
"_id": ObjectId("5d6f6d25e079b9fb7d858236"),
"first_name": "Aaron",
"is_finished": false,
"last_name": "Potter",
"user_id": ObjectId("5d6f6d25e079b9fb7d858236")
},
{
"_id": ObjectId("5d8b522d0cf2579e27bc8ce3"),
"first_name": "Harry",
"is_finished": true,
"last_name": "Paul",
"user_id": ObjectId("5d8b522d0cf2579e27bc8ce3")
}
]
}
]
注意:根据@Valijon 的建议,如果您需要从此处稍微重新安排,您可以添加一个 $project 阶段。
我正在尝试进行查询,其中我有一个 db_task
查询,其中包含任务 ID 和分配给它的用户。我必须获取 db_user 集合中存在的用户详细信息,并将传入的详细信息添加到同一文档中。
db_task
{
"_id" : ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users" : [
{
"user_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"is_finished" : false
},
{
"user_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"is_finished" : false
}
]
}
用户字段分配了该任务的用户,我想对 db_user
查询进行查找,这将使我获得同一嵌入式文档中的详细信息。
db_user
{
"_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"first_name" : "Harry",
"last_name" : "Paul"
},
{
"_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"first_name" : "Aaron",
"last_name" : "Potter"
}
我尝试使用 "users.user_id" 在 db_user table 上进行 $lookup,但这会为我获取一个新字段,然后我尝试将这些数组与“$concatArrays”连接起来但是结果还是不是我想的那样。
我想以类似这样的格式获得输出
db_task
{
"_id" : ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users" : [
{
"user_id" : ObjectId("5d8b522d0cf2579e27bc8ce3"),
"is_finished" : false,
"user_info":{
"first_name" : "Harry",
"last_name" : "Paul"
}
},
{
"user_id" : ObjectId("5d6f6d25e079b9fb7d858236"),
"is_finished" : false,
"user_info":{
"first_name" : "Aaron",
"last_name" : "Potter"
}
}
]
}
它适合你。
db_task.aggregate([
{
$match: { '_id': ObjectId("5d8b522d0cf2579c57bc8ce0") }
},
{
$unwind: '$users'
},
{
$lookup: {
from: 'db_user',
localField: 'users.user_id',
foreignField: '_id',
as: 'user_info'
}
},
{
$project: {
$users: {
user_id: 1,
is_finished: 1,
user_info:'$user_info',
}
}
},
{
$group: {
_id: '$_id',
users: {
$push: '$users'
},
}
},
])
几乎与 vishal pankhaniya 解决方案相同,但我们从内部文档
中排除了user_info._id
db.db_task.aggregate([
{
$unwind: "$users"
},
{
$lookup: {
from: "db_user",
localField: "users.user_id",
foreignField: "_id",
as: "user_info"
}
},
{
$project: {
users: {
user_id: 1,
is_finished: 1,
user_info: "$user_info"
}
}
},
{
$group: {
_id: "$_id",
users: {
$push: "$users"
}
}
},
{
$project: {
"users.user_info._id": 0
}
}
])
结果
[
{
"_id": ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users": [
{
"is_finished": false,
"user_id": ObjectId("5d8b522d0cf2579e27bc8ce3"),
"user_info": [
{
"first_name": "Harry",
"last_name": "Paul"
}
]
},
{
"is_finished": false,
"user_id": ObjectId("5d6f6d25e079b9fb7d858236"),
"user_info": [
{
"first_name": "Aaron",
"last_name": "Potter"
}
]
}
]
}
]
虽然他们在工作,但所提供的解决方案,包括放松和分组,在资源方面可能是昂贵的。 这里有一个更好的解决方案,只需要两个阶段:
db.db_task.aggregate([
{
$lookup: {
from: "db_user",
localField: "users.user_id",
foreignField: "_id",
as: "usersInfos"
}
},
{
$project: {
users: {
$map: {
input: "$usersInfos",
as: "ui",
in: {
$mergeObjects: [
"$$ui",
{
$arrayElemAt: [
{
$filter: {
input: "$users",
as: "users",
cond: {
$eq: [
"$$users.user_id",
"$$ui._id"
]
}
}
},
0
]
}
]
}
}
}
}
}
])
会输出
[
{
"_id": ObjectId("5d8b522d0cf2579c57bc8ce0"),
"users": [
{
"_id": ObjectId("5d6f6d25e079b9fb7d858236"),
"first_name": "Aaron",
"is_finished": false,
"last_name": "Potter",
"user_id": ObjectId("5d6f6d25e079b9fb7d858236")
},
{
"_id": ObjectId("5d8b522d0cf2579e27bc8ce3"),
"first_name": "Harry",
"is_finished": true,
"last_name": "Paul",
"user_id": ObjectId("5d8b522d0cf2579e27bc8ce3")
}
]
}
]
注意:根据@Valijon 的建议,如果您需要从此处稍微重新安排,您可以添加一个 $project 阶段。