'How to project only the fields present in an array in MongoDB?
there is a document schema that has an array field called "updatedFields" which contains some fields names that you will find in "oldDocument" and
"newDocument" objects. Here is its picture.
Now I want to project only those fields which exist in "updatedFields" array from "newDocument" and "oldDocument" like below:
$project : {
"oldDocument.Modified":1,
"oldDocument.Status":1,
"newDocument.Modified":1,
"newDocument.Status":1
}
Does anyone know how to build the project clause base on the fields' names in the array? I need a MongoDB query, not js code.
Solution 1:[1]
You can use $objectToArray in order to format the keys as values, $filter them according to the updatedFields array and then use $arrayToObject to make them keys again.
Edit: using $map inside the filter to cast dates to strings, according to a request on the comments.
Something like this:
db.collection.aggregate([
{
$project: {
oldDocumentArr: {$objectToArray: "$oldDocument"},
newDocumentArr: {$objectToArray: "$newDocument"},
updatedFields: 1
}
},
{
$project: {
oldDocumentFilter: {
$map: {
input: {
$filter: {
input: "$oldDocumentArr",
as: "item",
cond: {$in: ["$$item.k", "$updatedFields"]
}
}
},
"as": "obj",
"in": {
"k": "$$obj.k",
"v": {$toString: "$$obj.v"}
}
}
},
newDocumentFilter: {
$map: {
input: {
$filter: {
input: "$newDocumentArr",
as: "item",
cond: {$in: ["$$item.k", "$updatedFields"]
}
}
},
"as": "obj",
"in": {
"k": "$$obj.k",
"v": {$toString: "$$obj.v"}
}
}
}
}
},
{
$project: {
oldDocument: {$arrayToObject: "$oldDocumentFilter"},
newDocument: {$arrayToObject: "$newDocumentFilter"},
_id: 0
}
}
])
As you can see on the playground
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

