I have this document:
JSON:
[
{
"website": {
"id": 1,
"name": "website-1"
},
"_id": "64510561da44c5dc5b0e8935",
"items": [
{
"coin": {
"id": 1,
"title": "x"
},
"price": 53410,
"_id": "64510561da44c5dc5b0e8936"
},
{
"coin": {
"id": 2,
"title": "y"
},
"price": 2000,
"_id": "64510561da44c5dc5b0e8937"
}
]
},
{
"website": {
"id": 2,
"name": "website-2"
},
"_id": "645105ff86b991ba179b32f7",
"items": [
{
"coin": {
"id": 1,
"title": "x"
},
"price": 7250,
"_id": "645105ff86b991ba179b32f8"
},
{
"coin": {
"id": 3,
"title": "z"
},
"price": 888,
"_id": "645105ff86b991ba179b32f9"
},
{
"coin": {
"id": 4,
"title": "w"
},
"price": 444,
"_id": "645105ff86b991ba179b32fa"
}
]
},
{
"website": {
"id": 3,
"name": "website-3"
},
"_id": "245105ff86b991ba179b32f7",
"items": [
{
"coin": {
"id": 4,
"title": "w"
},
"price": 333,
"_id": "845105ff86b991ba179b32fa"
}
]
}
]
What I want:
websiteId
coinId
items
in result: In each record of result if we check the items
, every items be included that coin.id
is in coinIds
arrayWhat I expect as JSON:
[
{
"website": {
"id": 1,
"name": "website-1"
},
"_id": "64510561da44c5dc5b0e8935",
"items": [
{
"coin": {
"id": 1,
"title": "x"
},
"price": 53410,
"_id": "64510561da44c5dc5b0e8936"
},
{
"coin": {
"id": 2,
"title": "y"
},
"price": 2000,
"_id": "64510561da44c5dc5b0e8937"
}
]
},
{
"website": {
"id": 2,
"name": "website-2"
},
"_id": "645105ff86b991ba179b32f7",
"items": [
{
"coin": {
"id": 1,
"title": "x"
},
"price": 7250,
"_id": "645105ff86b991ba179b32f8"
}
]
}
]
My current code:
const websiteIds = [1,2];
const coinIds = [1,2];
const result = await MyModel.find(
{
'website.id': { $in: websiteIds },
'items.coin.id': { $in: coinIds },
}
);
It return correct filtered records by websiteIds
but in each record all items of items
field be returned if coin.id
of one of items be matched with coinIds
. I want Items
in returned JSON be filtered by coinIds
.
Since you want to be able to project more than one item, a simple find
with projection will not do the job. One option is to use a pipeline with $filter
:
const result = await MyModel.aggregate([
{$match: {
"website.id": {$in: websiteIds},
"items.coin.id": {$in: coinIds}
}},
{$set: {
items: {$filter: {
input: "$items",
cond: {$in: ["$$this.coin.id", coinIds]}
}}
}}
])
See how it works on the playground example