How can I remove just one element of an array in a collection like this:
{
"_id" : "Y9BBFa4c4vMiAkjbi",
"metadata" : {
"tags" : [
"Anything",
"Something",
"More"
]
}
}
In this example I just want to remove 'Something' - if it is existing.
var tag = 'Something';
if (Collection.find({ 'metadata.tags': tag }).count()) {
Collection.update(
{ _id: id },
{ $pull: { 'metadata.tags': tag } }
);
}
Just make sure your $pulltargets the array element you want to remove:
Collection.update({ _id: id },
{ $pull: { 'metadata.tags': { $eq: "Something" }}}
);
Related
I am trying to insert a time object into the times array for a specific activity name for a specific user. For example, if the user was "someuser" and I wanted to add a time to the times for guitar I am unsure as to what to do.
{
username: "someuser",
activities: [
{
name: "guitar",
times: []
},
{
name: "code",
times: []
}
]
}, {
username: "anotheruser",
activities: []
}
This is currently the function that I have, I cannot figure out what I am doing wrong, any help would be greatly appreciated:
function appendActivityTime(user, activityName, newRange) {
User.updateOne(
{username: user, 'activities.name': activityName},
{ $push: {'activities.$.times': {newRange}},
function (err) {
if (err) {
console.log(err);
} else {
console.log("Successfully added time range: " + newRange);
}
}}
);
}
appendActivityTime("someuser", "guitar", rangeObject);
i've tried your attempt and it worked for me:
db.getCollection("test").updateOne(
{ username: "someuser", "activities.name": "guitar" },
{ $push: { "activities.$.times": { from: ISODate(), to: ISODate() } } } //Don't worry about ISODate() in node.js use date objects
)
results:
{
"_id" : ObjectId("5f6c384af49dcd4019982b2c"),
"username" : "someuser",
"activities" : [
{
"name" : "guitar",
"times" : [
{
"from" : ISODate("2020-09-24T06:15:03.578+0000"),
"to" : ISODate("2020-09-24T06:15:03.578+0000")
}
]
},
{
"name" : "code",
"times" : [
]
}
]
}
what i would suggest you using instead is arrayFilter, they are much more precise and when you get used to them, they became very handy
If you are not confident with updating nested documents, let mongoose make the query.
let document = await Model.findOne ({ });
document.activities = new_object;
await document.save();
I am struggling to create an aggregate query for my MongoDB database.
here is my input array
recipients = [1,2,7]
here is my database collection
{
"chapter": 1,
"targets": [
{
type: 'user',
recipient: 1
}
]
},
{
"chapter": 1,
"targets": [
{
type: 'user',
recipient: 2
}
]
},
{
"chapter": 2,
"targets": [
{
type: 'user',
recipient: 3
}
]
},
{
"chapter": 3,
"targets": [
{
type: 'user',
recipient: 4
}
]
},
the desired output
should be [] because 7 doesn't exist in targets.recipient in the collection
here is what I've tried so far
db.collection.aggregate([
{
$match: {
'targets.recipient': { $in: recipients },
},
}
])
Any suggestions, thank you.
The way $in works is that it returns the document if there's any match between it's value and the array you're passing as a parameter. It looks like in your case you can use $in for initial filtering but then you want to return the result only if the result set contains all the values from the input array. In order to achieve it you can use $group to get all matching results and then apply $all:
db.collection.aggregate([
{
$match: { "targets.recipient": { $in: [1,2,7] } }
},
{
$group: {
_id: null,
docs: { $push: "$$ROOT" }
}
},
{
$match: { "docs.targets.recipient": { $all: [1,2,7] } }
}
])
Mongo Playground
// only matched documents will be shown.
> db.targets.aggregate([ {$match:{"targets.recipient":{$in:[1,2,7]}}}, {$project:{chapter:1,targets:1}} ]).pretty();
{
"_id" : ObjectId("5f5de14c598d922a1e6eff4d"),
"chapter" : 1,
"targets" : [
{
"type" : "user",
"recipient" : 1
}
]
}
{
"_id" : ObjectId("5f5de14c598d922a1e6eff4e"),
"chapter" : 1,
"targets" : [
{
"type" : "user",
"recipient" : 2
}
]
}
>
I have pull friend request when it is accepted or canceled. So, when I try to pull it from array, it doesn't work.
It matches for 1 document but 0 document modified.
When I delete the requested_at field from user field, it works well.
Where do I make mistake at ?
MongoDB Document
{
"_id" : ObjectId("5cb18680aa024b2d441f93cc"),
"friends" : [],
"friend_requests" : [
{
"user" : {
"id" : ObjectId("5cb14fd7db537905c89e0a72"),
"requested_at" : ISODate("2019-04-14T17:51:00.588Z")
}
}
]
}
MongoDB Query
db.getCollection('users').updateOne(
{ _id: ObjectId("5cb18680aa024b2d441f93cc") },
{
$pull: {
friend_requests: {
user: {
id: ObjectId("5cb14fd7db537905c89e0a72")
}
}
}
});
Result
{
"acknowledged" : true,
"matchedCount" : 1.0,
"modifiedCount" : 0.0
}
Use dot notation to specify a condition:
db.users.updateOne(
{ _id: ObjectId("5cb18680aa024b2d441f93cc") },
{
$pull: {
"friend_requests": {
"user.id": ObjectId("5cb14fd7db537905c89e0a72")
}
}
});
Unfortunately I got some false objects in an array in some documents, which are structured like this:
{
"_id" : "8vJY4baMbdYkgHian",
"title" : "Cars",
"tradename" : [
{
},
{
"element" : "Audi"
},
{
"element" : "Mercedes"
}
]
}
As you can see in this example, the first object in the array is empty. How can I remove empty objects in all tradename-arrays of all documents in the collection?
Collection.update(
{ 'tradename': {} },
{ $pull: { 'tradename.$': '' } }
);
An alternative approach to remove empty objects from an array with no assumptions:
db.a.update(
{"tradename": {}},
{ $pull: { 'tradename': {$in:[{}]} } },
{ "multi": true }
);
The following update operation using $pull updates all documents in the collection to remove empty objects from the array tradename, given that the embedded document has the element property only:
db.collection.update(
{ },
{ "$pull": { "tradename": { "element": { "$exists": false } } } },
{ "multi": true }
)
I would like the nested object with the id BAHx9KeKjuMePce6f to be updated:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"target" : [
{
"title" : "content",
"id" : "ePce6fBAHx9KeKjuM"
},
{
"title" : "content",
"id" : "BAHx9KeKjuMePce6f" <--
}
]
}
So this is what I tried:
var newData = { title: "new", one: "more", id: 'BAHx9KeKjuMePce6f' };
Collection.update(
{ _id: 'sgG6G9XTvvjj7uxwQ', 'target.id': 'BAHx9KeKjuMePce6f' },
{ $set: newData }
);
The result should be:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"target" : [
{
"title" : "content",
"id" : "ePce6fBAHx9KeKjuM"
},
{
"title": "new",
"one": "more",
"id" : "BAHx9KeKjuMePce6f"
}
]
}
In order to update specific element in array you can use mongodb positional $ operator.
Try the following query:
var newData = { title: "new", one: "more", id: 'BAHx9KeKjuMePce6f' };
Collection.update(
{ _id: 'sgG6G9XTvvjj7uxwQ', 'target.id': 'BAHx9KeKjuMePce6f' },
{ $set: { 'target.$': newData } }
);
You need the use the positional parameter $ to indicate you want to update the array element, rather than the root of the document, see the documentation:
Collection.update({
_id: 'sgG6G9XTvvjj7uxwQ',
'target.id': 'BAHx9KeKjuMePce6f'
}, {
$set: {
"target.$": newData
}
});