Return 文档如果只有子文档元素在嵌套数组中匹配
Return document if only sub-document elements matched within a nested array
主要集合是 User,我们有一个 User profile 集合,其中包含体验详情和其他内容。此外,我们还有一个 技能 集合。
用户
[{
"_id": "5f1eef8ec68d306fbbf13b0f",
"name": "John Davis",
"email": "John@gmail.com",
"__v": 0
},
{
"_id": "9q1eef8ec68d306fbbf13bh6",
"name": "Mik Luca",
"email": "Mik@gmail.com",
"__v": 0
}]
用户个人资料
[{
"_id": "5f1eef8ec68d306fbbf13b10",
"other_skills": [
null
],
"user_id": "5f1eef8ec68d306fbbf13b0f",
"phone_number": "1234569870",
"location": "5f16b72617fee02922688751",
"primary_skills": [
{
"_id": "5f32635cf764cc40447503a6",
"years": 1,
"skill_id": "5f0da75907a96c3040b3667d"
}
]
},
{
"_id": "5f1eef8ec68d306fbbf13b10",
"other_skills": [
null
],
"user_id": "9q1eef8ec68d306fbbf13bh6",
"phone_number": "1234569870",
"location": "5f16b72617fee02922688751",
"primary_skills": [
{
"_id": "6s0da75907a96c3040b36690",
"years": 1,
"skill_id": "5f0da75907a96c3040b3667d"
}
]
}]
技能
[{
"_id": "5f0da75907a96c3040b3667d",
"skill": "Mongo"
},
{
"_id": "6s0da75907a96c3040b36690",
"skill": "Node"
}]
我需要列出用户及其用户个人资料信息,还需要使用技能进行过滤
我试过了
db.getCollection("users").aggregate(
[
{
"$project" : {
"_id" : NumberInt(0),
"users" : "$$ROOT"
}
},
{
"$lookup" : {
"localField" : "users._id",
"from" : "userprofiles",
"foreignField" : "user_id",
"as" : "userprofiles"
}
},
{
"$unwind" : {
"path" : "$userprofiles",
"preserveNullAndEmptyArrays" : true
}
},
{
"$lookup" : {
"localField" : "userprofiles.primary_skills.skill_id",
"from" : "skills",
"foreignField" : "_id",
"as" : "skills"
}
},
{
"$unwind" : {
"path" : "$skills",
"preserveNullAndEmptyArrays" : true
}
},
{
"$match" : {
"skills._id" : ObjectId("5f0dce8d07a96c3040b36687")
}
}
],
{
"allowDiskUse" : true
}
);
但没有得到正确的结果。
如何使用 User 列表填充 user profile 和 skill 信息以及使用技能 ID 过滤用户列表?
问候和感谢。
您可以使用带管道的查找来匹配查找内部的过滤器,
$lookup
与 userProfile
collection
- 管道
$match
以匹配配置文件 ID
- 像
skill_id
这样的配置文件的其他过滤器在此处匹配
$unwind
解构 primary_skills
数组,因为我们要使用 skill_id 进行查找
$lookup
将 skills
collection
$unwind
解构 primary_skills.skill_id
数组,因为我们需要它作为 object
$grpup
重构primary_skills
数组
$match
if userProfiles
不等于空 []
db.users.aggregate([
{
$lookup: {
from: "usersProfile",
let: { id: "$_id" },
as: "userProfiles",
pipeline: [
{
$match: {
$expr: { $eq: ["$$id", "$user_id"] },
// match here user profile filters
"primary_skills.skill_id": "5f0da75907a96c3040b3667d"
}
},
{ $unwind: "$primary_skills" },
{
$lookup: {
from: "skills",
localField: "primary_skills.skill_id",
foreignField: "_id",
as: "primary_skills.skill_id"
}
},
{ $unwind: "$primary_skills.skill_id" },
{
$group: {
_id: "$_id",
other_skills: { $first: "$other_skills" },
phone_number: { $first: "$phone_number" },
location: { $first: "$location" },
primary_skills: {
$push: {
_id: "$primary_skills._id",
skill: "$primary_skills.skill_id.skill",
years: "$primary_skills.years"
}
}
}
}
]
}
},
{ $match: { userProfiles: { $ne: [] } } }
])
主要集合是 User,我们有一个 User profile 集合,其中包含体验详情和其他内容。此外,我们还有一个 技能 集合。
用户
[{
"_id": "5f1eef8ec68d306fbbf13b0f",
"name": "John Davis",
"email": "John@gmail.com",
"__v": 0
},
{
"_id": "9q1eef8ec68d306fbbf13bh6",
"name": "Mik Luca",
"email": "Mik@gmail.com",
"__v": 0
}]
用户个人资料
[{
"_id": "5f1eef8ec68d306fbbf13b10",
"other_skills": [
null
],
"user_id": "5f1eef8ec68d306fbbf13b0f",
"phone_number": "1234569870",
"location": "5f16b72617fee02922688751",
"primary_skills": [
{
"_id": "5f32635cf764cc40447503a6",
"years": 1,
"skill_id": "5f0da75907a96c3040b3667d"
}
]
},
{
"_id": "5f1eef8ec68d306fbbf13b10",
"other_skills": [
null
],
"user_id": "9q1eef8ec68d306fbbf13bh6",
"phone_number": "1234569870",
"location": "5f16b72617fee02922688751",
"primary_skills": [
{
"_id": "6s0da75907a96c3040b36690",
"years": 1,
"skill_id": "5f0da75907a96c3040b3667d"
}
]
}]
技能
[{
"_id": "5f0da75907a96c3040b3667d",
"skill": "Mongo"
},
{
"_id": "6s0da75907a96c3040b36690",
"skill": "Node"
}]
我需要列出用户及其用户个人资料信息,还需要使用技能进行过滤
我试过了
db.getCollection("users").aggregate(
[
{
"$project" : {
"_id" : NumberInt(0),
"users" : "$$ROOT"
}
},
{
"$lookup" : {
"localField" : "users._id",
"from" : "userprofiles",
"foreignField" : "user_id",
"as" : "userprofiles"
}
},
{
"$unwind" : {
"path" : "$userprofiles",
"preserveNullAndEmptyArrays" : true
}
},
{
"$lookup" : {
"localField" : "userprofiles.primary_skills.skill_id",
"from" : "skills",
"foreignField" : "_id",
"as" : "skills"
}
},
{
"$unwind" : {
"path" : "$skills",
"preserveNullAndEmptyArrays" : true
}
},
{
"$match" : {
"skills._id" : ObjectId("5f0dce8d07a96c3040b36687")
}
}
],
{
"allowDiskUse" : true
}
);
但没有得到正确的结果。
如何使用 User 列表填充 user profile 和 skill 信息以及使用技能 ID 过滤用户列表?
问候和感谢。
您可以使用带管道的查找来匹配查找内部的过滤器,
$lookup
与userProfile
collection- 管道
$match
以匹配配置文件 ID - 像
skill_id
这样的配置文件的其他过滤器在此处匹配 $unwind
解构primary_skills
数组,因为我们要使用 skill_id 进行查找
$lookup
将skills
collection$unwind
解构primary_skills.skill_id
数组,因为我们需要它作为 object$grpup
重构primary_skills
数组$match
ifuserProfiles
不等于空[]
db.users.aggregate([
{
$lookup: {
from: "usersProfile",
let: { id: "$_id" },
as: "userProfiles",
pipeline: [
{
$match: {
$expr: { $eq: ["$$id", "$user_id"] },
// match here user profile filters
"primary_skills.skill_id": "5f0da75907a96c3040b3667d"
}
},
{ $unwind: "$primary_skills" },
{
$lookup: {
from: "skills",
localField: "primary_skills.skill_id",
foreignField: "_id",
as: "primary_skills.skill_id"
}
},
{ $unwind: "$primary_skills.skill_id" },
{
$group: {
_id: "$_id",
other_skills: { $first: "$other_skills" },
phone_number: { $first: "$phone_number" },
location: { $first: "$location" },
primary_skills: {
$push: {
_id: "$primary_skills._id",
skill: "$primary_skills.skill_id.skill",
years: "$primary_skills.years"
}
}
}
}
]
}
},
{ $match: { userProfiles: { $ne: [] } } }
])