The data in my database is as follows:
/* 1 */
{
"name": "Severus",
"u_name": "severussnape",
"info": [
{
"value": "Severus",
"source": "1",
"infotag": "name"
},
{
"value": "severussnape",
"source": "2",
"infotag": "name"
}
]
}
/* 2 */
{
"name": "Harry",
"u_name": null,
"info": [
{
"value": "Harry",
"source": "1",
"infotag": "name"
}
]
}
I'd like to project the data so that the name
field and the info
array in the result are changed based on whether or not the u_name
field is null. The result I expect looks like so:
/* 1 */
{
"name": "severussnape",
"info": [
{
"value": "severussnape",
"source": "2",
"infotag": "name"
}
]
}
/* 2 */
{
"name": "Harry",
"info": [
{
"value": "Harry",
"source": "1",
"infotag": "name"
}
]
}
I've managed to project the name field correctly using the projection:
db.database.aggregate([{
$project:{
"name":{$cond:[{$eq:["$u_name",null]},"$name","$u_name"]}
}
}])
But I've been unable to figure out how to remove the array element from info
with value "Severus" in the first document depending on u_name
. Is this possible?
You should try this aggregate query, this will solve your problem.
db.database.aggregate([
{
$project:{
'name': {
'$ifNull': ['$u_name', '$name']
},
'info': '$info'
}
},
{
$project: {
'name': '$name',
'info': {
'$filter': {
'input': '$info',
'as': 'info',
'cond': {
'$eq':['$$info.value', '$name']
}
}
}
}
}
])