mongodb - 具有深度嵌套数组的 MongoDB 查找
问题描述
我有一个找不到解决方案的问题。
我有一个带有深度嵌套数组的集合“介质”,其中通过 ObjectID 对人员集合的引用。
中等收藏:
{
"title": "Test Medium",
"mediumMetaData": {
"metaData": [{
"movietype": "movie",
"year": 2019,
"language": "german",
"personInformation": {
"actor": [{
"actors": "5e2c3b1daf0ba75b00415bb0"
}],
"director": [{
"directors": "5e2c3b1daf0ba75b00415bb0"
}],
"screenwriter": [{
"screenwriters": "5e2c3b1daf0ba75b00415bb0"
}],
"camera": [{
"cameras": "5e2c3b81af0ba75b00415bb1"
}]
}
}]
},
"createdById": "5dcb108b59057b22702ecaa9"
}
人员集合应通过“ _id ”字段匹配。
现在我的问题。我想通过引用 Person 中的所有 objectId 来构建聚合查询。
我现在尝试了几种方法,但查找根本不匹配:
这是我现在尝试的,但是 actor-tag 一直是空的:前两个阶段正在工作,据我所知,我需要两个展开,每个数组部分一个。
db.getCollection("medium").aggregate(
[
{
"$match" : {
"_id" : ObjectId("5e2c3d9002d512c71cda8006")
}
},
{
"$unwind" : {
"path" : "$mediumMetaData.metaData",
"preserveNullAndEmptyArrays" : false
}
},
{
"$unwind" : {
"path" : "$mediumMetaData.metaData.personInformation.actor",
"preserveNullAndEmptyArrays" : false
}
},
{
"$lookup" : {
"from" : "person",
"let" : {
"actor_id" : "$mediumMetaData.metaData.personInformation.actor.actors"
},
"pipeline" : [
{
"$match" : {
"$expr" : [
{
"$eq" : [
"$_id",
"$$$actor_id"
]
}
]
}
},
{
"$project" : {
"_id" : 0.0
}
}
],
"as" : "actor1"
}
}
],
{
"allowDiskUse" : false
}
);
有人可以帮忙吗?
解决方案
试试这个查询:
db.medium.aggregate([{ $match: { "_id": ObjectId("5e2df451d02e05b69467d1bc") } },
{ $unwind: '$mediumMetaData.metaData' },
{
$lookup:
{
from: "Person",
let: {
actor: "$mediumMetaData.metaData.personInformation.actor", director: "$mediumMetaData.metaData.personInformation.director",
screenwriter: "$mediumMetaData.metaData.personInformation.screenwriter", camera: "$mediumMetaData.metaData.personInformation.camera"
},
pipeline: [
{
$project: {
name: 1,
personID: {
$let:
{
vars: { id: '$_id' },
in: { $toString: "$$id" }
}
}
}
},
{
$match:
{
$expr:
{
$or:
[
{ $in: ['$personID', "$$actor.actors"] },
{ $in: ['$personID', "$$director.directors"] },
{ $in: ['$personID', "$$screenwriter.screenwriters"] },
{ $in: ['$personID', "$$camera.cameras"] }
]
}
}
}, { $project: { personID: 0 } }
],
as: "personInfo"
}
}, { $unwind: { path: "$personInfo", preserveNullAndEmptyArrays: true } },
{ $group: { _id: '$_id', 'metaData': { $addToSet: '$mediumMetaData.metaData' },
personInfo: { $push: '$personInfo' }, title: { $first: '$title' }, createdById: { $first: '$createdById' } } },
{ $project: { 'mediumMetaData.metaData': '$metaData', createdById: 1, title: 1, personInfo: 1 } }
])
注意:如果你 "actors": "5e2c3b1daf0ba75b00415bb0"/"directors": "5e2c3b1daf0ba75b00415bb0"
是ObjectId()
而不是strings
,那么你可以通过比较类似的东西来避免两个$project
阶段pipeline
{ $in: ['$_id', "$$actor.actors"] }
测试: MongoDB-游乐场
推荐阅读
- laravel - 尝试在调用 Laravel Api 时访问 VueJs 上 null 类型值的数组偏移量
- python - scipy.sparse.csr_matrix 和 scipy.sparse.lil_matrix 有什么不同
- mqtt - 在 MQTT 规范中,为什么我们不能在订阅时为主题设置“别名”?
- timedelta - 如何在 Delta History Metadata 中填充 Delta IO 作业字段
- ruby-on-rails - Rails 迁移将时间更改为保留数据的日期时间
- java - Android Studio 无法识别 Java 类中间的 Kotlin 类
- r - 如何绘制相同变量的 2 个,但来自同一图表上的 2 个不同的人
- kubernetes - 如何将 CNAME 指向 OpenShift 路由
- azure-pipelines - Azure DevOps YAML 管道 BuildApi:有没有办法获得阶段依赖值?
- javascript - 当位置从绝对变为固定时如何使元素保持在原位