我的文档具有以下结构:
{
_id: "UNIQUE_ID",
myarray: [
{
mykey: '12345',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '67890',
// other fields
}
]
}
]
}
我需要返回myarray
(在mykey
或myarray
上属于一组值的nestedarray
上的所有项目。例如,对于上面的文档,如果一组值是['12345, '67890']
,则应返回myarray
中的两个项目。
我正在使用以下代码来做到这一点:
collection.aggregate([
{
$match: {
"_id": documentId,
$or: [
{ "myarray": {$elemMatch: {"mykey": { $in: ['12345, '67890'] } } } },
{ "myarray.$.nestedarray": {$elemMatch: {"mykey": { $in: ['12345, '67890'] } }} }
]
}
},
{
$project: {
myarray: {
$filter: {
input: '$myarray',
as: 'arrayitem',
cond: {
$or: [
{ $eq: ["$$arrayitem.mykey", '12345'] },
{ $eq: ["$$arrayitem.nestedarray.[$].mykey", '12345'] }
]
}
}
}
}
}
]);
但这只会返回mykey
级别在myarray
上匹配的项(在nestedarray
内部不匹配)。
我在做什么错了?
此外,如何在$ filter函数中使用集合['12345, '67890']
而不是单个值'12345'
?
澄清:
mykey
上的某个项目上有myarray
个匹配项,则包括该项目(此项目将没有nestedarray
字段)mykey
上的项与nestedarray
相匹配:包括myarray
中的项,其中包含nestedarray
(还包含nestedarray
的全部内容)。 myarray
中的此项将没有mykey
字段示例:
数据:
{
_id: "UNIQUE_ID",
myarray: [
{
mykey: '11111',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '22222',
// other fields
},
{
mykey: '84325',
// other fields
}
]
},
{
mykey: '645644',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '23242',
// other fields
},
{
mykey: '23433',
// other fields
}
]
}
]
}
一组值:['11111', '22222']
预期的查询结果:
{
_id: "UNIQUE_ID",
myarray: [
{
mykey: '11111',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '22222',
// other fields
},
{
mykey: '84325',
// other fields
}
]
}
]
}
答案 0 :(得分:2)
您可以使用以下汇总
db.collection.aggregate([
{ "$match": { "_id": documentId }},
{ "$project": {
"myarray": {
"$filter": {
"input": {
"$map": {
"input": "$myarray",
"as": "arrayitem",
"in": {
"mykey": "$$arrayitem.mykey",
"nestedarray": "$$arrayitem.nestedarray",
"aaaa": {
"$filter": {
"input": "$$arrayitem.nestedarray",
"as": "vv",
"cond": { "$in": ["$$vv.mykey", ["12345", "67890"]] }
}
}
}
}
},
"as": "ff",
"cond": {
"$or": [
{ "$in": ["$$ff.mykey", ["12345", "67890"]] },
{ "$gte": [{ "$size": { "$ifNull": ["$$ff.aaaa", []] }}, 1] }
]
}
}
}
}},
{ "$project": { "myarray.aaaa": 0 }}
])
这是工作中的example
答案 1 :(得分:2)
您可以使用单个$filter,然后以cond
的身份直接检查mykey
或将$anyElementTrue用于数组。
db.col.aggregate([
{
$project: {
myarray: {
$filter: {
input: "$myarray",
cond: {
$or: [
{ $in: [ "$$this.mykey", ["11111", "22222"] ] },
{ $anyElementTrue: [
{
$map: {
input: { $ifNull: [ "$$this.nestedarray", [] ] },
as: "na",
in: { $in: [ "$$na.mykey", ["11111", "22222"] ] }
}
}
]
}
]
}
}
}
}
}
])