my data structure is
[
{
"item": "journal",
"qty": 25,
"status": "A",
"weekNumber": 1,
"sortOrder": 1,
"label": 1,
"numberOfPossibleDays": 1,
"editable": 1,
"selectedDate": 1,
"deliveryDays": 1,
"products": [
{
"key": "item-one",
"name": "item one",
"tags": [
"v",
"b"
]
},
{
"key": "item-two",
"name": "item-two",
"tags": [
"a",
"c",
"d"
]
},
{
"_id": 3,
"name": "item-three",
"tags": [
"g"
]
}
]
},
{
"item": "notebook",
"status": "b",
"qty": 1,
"weekNumber": 1,
"sortOrder": 1,
"label": 1,
"numberOfPossibleDays": 1,
"editable": 1,
"selectedDate": 1,
"deliveryDays": 1,
"products": [
{
"key": "item-four",
"name": "item four",
"tags": [
"a",
"o"
]
},
{
"key": "item-five",
"name": "item-five",
"tags": [
"s",
"a",
"b"
]
}
]
}
]
and I want to find all the elements with tags 'a', so the expected response should be like
[
{
"_id": ObjectId("5a934e000102030405000000"),
"deliveryDays": 1,
"editable": 1,
"item": "journal",
"label": 1,
"numberOfPossibleDays": 1,
"products": [
{
"key": "item-one",
"name": "item one",
"tags": [
"v",
"b"
]
}
],
"qty": 25,
"selectedDate": 1,
"sortOrder": 1,
"status": "A",
"weekNumber": 1
},
{
"_id": ObjectId("5a934e000102030405000001"),
"deliveryDays": 1,
"editable": 1,
"item": "notebook",
"label": 1,
"numberOfPossibleDays": 1,
"products": [],
"qty": 1,
"selectedDate": 1,
"sortOrder": 1,
"status": "b",
"weekNumber": 1
}
]
I can use the $filter operator to filter the element containing "b" in the tags array for the products array in the projection. i think it's very lengthy code. is there any way that mongoDB send all the values instead of writing every element in the query like ?
db.collection.find({
"products.tags": "b"
},
{
item: 1,
qty: 1,
"status": 1,
"weekNumber": 1,
"sortOrder": 1,
"label": 1,
"numberOfPossibleDays": 1,
"editable": 1,
"selectedDate": 1,
"deliveryDays": 1,
products: {
$filter: {
input: "$products",
cond: {
$in: [
"v",
"$$this.tags"
]
}
}
}
})
CodePudding user response:
you could maybe use an aggreation as follows :
db.collection.aggregate([
{
$match: {
"products.tags": "b"
},
},
{
$set: {
products: {
$filter: {
input: "$products",
cond: {
$in: [
"v",
"$$this.tags"
]
}
}
}
}
}
])
It will give the same results as before, but you won't have to write every field with field : 1
to keep them.