I have a documents in MongoDB, one of them looks like this:
{
\"_id\" : 100,
\"name\" : \"Something\",
\"items\" : [
{
\"item\" : 47,
\"c
If you are not restricted to having the query be in one single step, you could try:
step 1) use the aggregate function with the $unwind and $group operators to find the minimum item for each document
myresults = db.megas.aggregate( [ { "$unwind": "$items" },
{"$group": { '_id':'$_id' , 'minitem': {'$min': "$items.item" } } } ] )
step 2) the loop through the results and $pull the element from the array
for result in myresults['result']:
db.megas.update( { '_id': result['_id'] },
{ '$pull': { 'items': { 'item': result['minitem'] } } } )
Please find my solution written in plain javascript. It should work straight through MongoDb shell
cursor = db.students.aggregate(
[{ "$unwind": "$items" },
{ "$match": { "items.color": "green"}},
{ "$group": {'_id': '$_id', 'minitem': {
'$min': "$items.item"
}
}
}
]);
cursor.forEach(
function(coll) {
db.students.update({
'_id': coll._id
}, {
'$pull': {
'items': {
'item': coll.minitem
}
}
})
})
Starting in Mongo 4.4, the $function aggregation operator allows applying a custom javascript function to implement behaviour not supported by the MongoDB Query Language.
And coupled with improvements made to db.collection.update() in Mongo 4.2 that can accept an aggregation pipeline, allowing the update of a field based on its own value,
We can manipulate and update an array in ways the language doesn't easily permit:
// {
// "name" : "Something",
// "items" : [
// { "item" : 47, "color" : "red" },
// { "item" : 39, "color" : "blue" },
// { "item" : 44, "color" : "green" }
// ]
// }
db.collection.update(
{},
[{ $set:
{ "items":
{ $function: {
body: function(items) {
var min = Math.min(...items.map(x => x.item));
return items.filter(x => x.item != min);
},
args: ["$items"],
lang: "js"
}}
}
}],
{ multi: true }
)
// {
// "name" : "Something",
// "items" : [
// { "item" : 47, "color" : "red" },
// { "item" : 44, "color" : "green" }
// ]
// }
$function takes 3 parameters:
body, which is the function to apply, whose parameter is the array to modify. The function here simply consists in first finding the minimum item from the array in order to then filter it out.args, which contains the fields from the record that the body function takes as parameter. In our case, "$items".lang, which is the language in which the body function is written. Only js is currently available.