我有一个数组:
[
{
id: 1,
name: 1,
list: [
{
id: 11,
name: 11,
list: [
[
{ id: 111, name: 111 },
{ id: 112, name: 112 }
]
]
}
]
},
{
id: 6,
name: 6,
list: [
{
id: 62,
name: 12,
list: [ [ { id: 111, name: 111 } ] ]
}
]
}
]
希望过滤二级列表数组,使用命令如下
{
$project: {
id: 1, name: 1,
list: {
id: 1, name: 1,
list: {
$filter: {
input: '$list.list',
as: 'item',
cond: { $eq: ['$$item.name', 111] }
}
}
}
}
}
却没有得到预期的结果。完整的过滤器代码如下:
db.runoob.aggregate([{ $match: { $or: [{ 'name': 1, 'list.name': { $eq: 11 } }, { name: 6, 'list.name': { $eq: 12 } }] } }, { $project: { id:1, name: 1, 'list': { $filter: { input: '$list', as: 'item', cond: { $or: [{ $and: [{ $in: ['$$item.id', [11, 12]] }, {$eq: ['$$item.name', 11]}] }, { $and: [{ $in: ['$$item.id', [61, 62]] }, {$eq: ['$$item.name', 12]}] }] } } } } }, { $project: { id: 1, name: 1, list: { id: 1, name: 1, list: { $filter: { input: '$list.list', as: 'item1', cond: { $eq: ['$$item1.name', 111] } } } } } }])
请帮帮我,谢谢^_^
我尝试使用 $unwind 如下
db.runoob.aggregate([{ $unwind: '$list' }, { $unwind: '$list.list' }, { $unwind: '$list.list.list' }, { $match: { $or: [{ 'name': 1, 'list.name': { $eq: 11 }, 'list.list.name': { $eq: 112 } }, { name: 6, 'list.name': { $eq: 12 } }] } } ])
但是这个命令会破坏结构
希望保留原来的数据结构,或者使用$unwind后还有其他方法恢复结构
参考本文内容:在此输入链接描述
我尝试编写如下代码:
db.collection.aggregate([
{
$match: {
$or: [
{
"name": 1,
"list.name": {
$eq: 11
}
},
{
name: 6,
"list.name": {
$eq: 12
}
}
]
}
},
{
$project: {
id: 1,
name: 1,
"list": {
$filter: {
input: "$list",
as: "item",
cond: {
$or: [
{
$and: [
{
$in: [
"$$item.id",
[
11,
12
]
]
},
{
$eq: [
"$$item.name",
11
]
}
]
},
{
$and: [
{
$in: [
"$$item.id",
[
61,
62
]
]
},
{
$eq: [
"$$item.name",
12
]
}
]
}
]
}
}
}
}
},
{
$project: {
id: 1,
name: 1,
list: {
$map: {
input: "$list",
as: "item1",
in: {
id: "$$item1.id",
name: "$$item1.name",
list: {
$filter: {
input: "$$item1.list",
as: "item2",
cond: {
$eq: [
"$$item2.name",
111
]
}
}
}
}
},
}
}
}
])
和
db.collection.aggregate([
{
"$addFields": {
"list": {
"$map": {
"input": "$list",
"as": "a1",
"in": {
id: "$$a1.id",
name: "$$a1.name",
list: {
"$map": {
"input": "$$a1.list",
"as": "a2",
"in": {
id: "$$a2.id",
name: "$$a2.name",
list: {
"$filter": {
"input": "$$a2.list",
"as": "a3",
"cond": {
$eq: [
"$$a3.name",
1111
]
}
}
}
}
}
}
}
}
}
}
},
])
这两种代码都能得到正确的结果。
因为我的数组嵌套层次会很深,有没有其他更好的选择?
如果你想保留原始数据,你应该在使用
replica
之前field
$unwind
。找到数据后,删除replica
db.runoob.aggregate([
{
$addFields: {
newlist: "$list"
}
},
{
$unwind: "$newlist"
},
{
$unwind: "$newlist.list"
},
{
"$match": {
"newlist.list.id": {
"$in": [
111
]
}
}
},
{
"$unset": "newlist"
}
])
操作
$match
也可以像下面这样:
{
"$match": {
"newlist.list.id": 111
}
}