I have documents with the following structure:
{
_id: "UNIQUE_ID",
myarray: [
{
mykey: '12345',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '67890',
// other fields
}
]
}
]
}
And I need to return all items from myarray on which mykey (on items of myarray or nestedarray) belongs to a set of values. For example, for the document above, if the set of values is ['12345, '67890'], both items from myarray should be returned.
I'm using the following code to do that:
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'] }
]
}
}
}
}
}
]);
But this only return the items on which mykey matches at myarray level (not matching it inside nestedarray).
What am I doing wrong?
Also, how may I use set ['12345, '67890'] instead of single value '12345' inside of $filter function?
Clarifying:
- If
mykeymatch is on an item frommyarray: include this item (this item will not have anestedarrayfield) - If
mykeymatch is on an item fromnestedarray: include the item frommyarraywhich containsnestedarray(also with full contents ofnestedarray). This item frommyarraywill not have amykeyfield
Example:
Data:
{
_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
}
]
}
]
}
Set of values: ['11111', '22222']
Expected query result:
{
_id: "UNIQUE_ID",
myarray: [
{
mykey: '11111',
// other fields
},
{
// other fields
nestedarray: [
{
mykey: '22222',
// other fields
},
{
mykey: '84325',
// other fields
}
]
}
]
}
mykeyexists innestedarraybut not inmyArray?myarraywhich containsnestedarrayshould be included, and only the matching item(s) fromnestedarrayshould be includednestedarraywill be required (even if only one of them matches).nestedarrayarray?