如何解决MongoDB:在第三级嵌入文档中找到匹配的元素
我是MongoDB的新手。我有一个典型的用例。这是我的单个文档JSON结构。
{
"category":"cat_1","_id": "id1","levels":[
{
"id":"l1","orders":[
{
"id":"o1","screens":[
{
"id":"l1o1s1","name":"screen1"
},{
"id": "l1o1s2","name": "screen2"
}
]
},{
"id": "o2","screens": [
{
"id": "l1o2s1","name": "screen3"
},{
"id": "l1o2s2","name": "screen4"
}
]
}
]
},{
"id": "l2","orders": [
{
"id": "o1","screens": [
{
"id": "l2o1s1","name": "screen5"
},{
"id": "l2o1s2","name": "screen6"
}
]
},"screens": [
{
"id": "l2o2s1","name": "screen7"
},{
"id": "l2o2s2","name": "screen8"
}
]
}
]
}
]
}
在这里,我只想获取给定屏幕ID的数据。例如,如果["l1o1s1","l1o2s2","l2o1s1","l2o2s1"]
是我应该在文档中找到的屏幕ID列表,
那么我想要的结果如下(它应该返回输入中仅给出的屏幕ID)
{
"category":"cat_1","name":"screen1"
}
]
},"screens": [
{
"id": "l1o2s2",]
},"name": "screen7"
}
]
}
]
}
]
}
屏幕的输入不必仅在单个文档中。它也可能存在于其他类别中。那么它应该只返回具有上述屏幕ID的文档。
有什么想法可以像这样检索数据吗?
解决方法
正如@ alex-blex所建议的那样,您的模式不支持这种查询,但是如果您仍然想要实现结果,则可以尝试使用聚合管道,但是效率可能不高。
您可以尝试以下聚合管道:
db.collection.aggregate([
{
"$match": {
"levels.orders.screens.id": {
$in: [
"l1o1s1","l1o2s2","l2o1s1","l2o2s1"
]
}
}
},{
"$unwind": "$levels"
},{
"$unwind": "$levels.orders"
},{
"$unwind": "$levels.orders.screens"
},{
"$match": {
"levels.orders.screens.id": {
$in: [
"l1o1s1",{
"$replaceRoot": {
"newRoot": {
_id: "$_id","category": "$category","levelId": "$levels.id","orderId": "$levels.orders.id","screens": "$levels.orders.screens"
}
}
},{
$group: {
_id: {
_id: "$_id","levelId": "$levelId","orderId": "$orderId",},"category": {
$first: "$category"
},"orderId": {
$first: "$orderId"
},"levelId": {
$first: "$levelId"
},"screens": {
$push: "$screens"
}
}
},{
$project: {
_id: "$_id._id",levelId: "$levelId",category: "category","orders": {
id: "$orderId",screens: "$screens"
}
}
},"orders": {
$push: "$orders"
}
}
},"levels": {
id: "$levelId",orders: "$orders"
}
}
},{
$group: {
_id: "$_id","levels": {
$push: "$levels"
}
}
},])
这是一个非常大且复杂的聚合管道,因此无法保证性能和效率,但是您可以检查一下是否适合您。
说明:
-
$match仅在聚合管道的后期阶段过滤出所需的文档集。
-
$unwind展开
levels
数组 -
$unwind展开
orders
数组 -
$unwind展开
screens
数组 -
$match以获得所需的确切
screens
-
$replaceRoot重新构造JSON文档,以便我们可以将展开的数组归组
-
$group将
screens
分组到屏幕数组 -
$project再次重组结果文档,以恢复原始结构
-
$group将
orders
分组到订单数组 -
$project再次重组结果文档,以恢复原始结构
-
$group将
levels
分组为levels数组并返回最终结果
或者,您可以直到第5阶段运行协商管道,然后将结果组合回后端代码中所需的格式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。