So i was trying to update data store in the mongodb database, using Mongoose
original data structure looks like this
{
"_id" : ObjectId("234u232kjrkjwebrkw"),
"local" : {
"password" : "sdflsdjflsdjlfkjsdlkfjklsdjflksd",
"email" : "email#email.com"
},
"__v" : 0
}
I'm trying to update the "userName" property in the "local". after which it supposed to be
{
"_id" : ObjectId("234u232kjrkjwebrkw"),
"local" : {
"password" : "sdflsdjflsdjlfkjsdlkfjklsdjflksd",
"email" : "email#email.com",
"userName" : "yowhatsup"
},
"__v" : 0
}
I used this
User.findByIdAndUpdate("54a490ab6e13cca1d47870d6", {local:{ userName: 'jasonBorne' }}, { upsert: true }, function(){})
it became this
{
"_id" : ObjectId("234u232kjrkjwebrkw"),
"local" : {
"userName" : "yowhatsup"
},
"__v" : 0
}
it's been overwritten.
how to avoid this?
note: the new "userName" is defined as {type:String,default:null} when the model was structred.
You can do an an update if exists, otherwise insert:
Arguments for update are: findQuery, data, queryOptions, onComplete
User.update({"_id" : ObjectId("234u232kjrkjwebrkw")}, { $set: { "local.userName": "whatsup" } }, { upsert: true }, function(err){...});
Related
I'm trying to swap out a regular mongo call for an aggregate call. the original that was working is ..
const account = await userModel
.findOne({ 'shared.username': username })
.exec();
console.log(account._id)
The new aggregate function is...
const account = await userModel.aggregate([
{
$match: {
'shared.username': username,
},
},
{
$lookup: {
as: 'photos',
foreignField: 'userId',
from: 'photos',
localField: '_id',
},
},
]);
console.log(account._id)
// ^ Error
The error im getting is
Property '_id' does not exist on type 'any[]'.ts(2339)
im sure their is _id being returned as i can see it in Studio 3T aggregation output
{
"_id" : ObjectId("5e10983cb182628af48e590a"),
"shared" : {
"currency" : "USD",
"followers" : 0,
"following" : 0,
"language" : "en",
"loggedIn" : true,
"twofactor" : false,
"warningMessage" : "verify",
"email" : "email#gmail.com",
"fullName" : "James",
"username" : "57fe31142e10",
"location" : "/57fe31142e10"
},
"photos" : [
{
"_id" : ObjectId("5e117b8f227a32597cdcbb6e"),
"category" : "Double Deckers",
"previewId" : "5e10983cb182628af48e590a/0f5d0010a4e55794419c03328184cfb45984bf43.jpg",
"published" : true,
"thumbnailId" : "5e10983cb182628af48e590a/54265d07a962f8544a9ebdc1d876775d9eeed471.jpg",
"userId" : ObjectId("5e10983cb182628af48e590a"),
"zoomId" : "5e10983cb182628af48e590a/fe0b2016a0be2b26259aaf5152ef22edfffa0c57.jpg",
"createdAt" : ISODate("2020-01-05T06:00:47.756+0000"),
"updatedAt" : ISODate("2020-01-05T06:00:47.756+0000"),
"__v" : 0
},
{
"_id" : ObjectId("5e11ab2f0f451779f70f89b1"),
"category" : "Single Decker",
"previewId" : "5e10983cb182628af48e590a/30d496e44faae1345e4c555accfdc6446fd11945.jpg",
"published" : true,
"thumbnailId" : "5e10983cb182628af48e590a/9293dd5517f694341a2e582df670dc9bbaba0763.jpg",
"userId" : ObjectId("5e10983cb182628af48e590a"),
"zoomId" : "5e10983cb182628af48e590a/0a038434e857b05ef8aa46da6dab01259ba2b03e.jpg",
"createdAt" : ISODate("2020-01-05T09:23:59.007+0000"),
"updatedAt" : ISODate("2020-01-05T09:23:59.007+0000"),
"__v" : 0
},
{
"_id" : ObjectId("5e11aba00f451779f70f89b2"),
"category" : "Midi",
"previewId" : "5e10983cb182628af48e590a/2267d14aa642d6cee86319909177ce4eef45cbcc.jpg",
"published" : true,
"thumbnailId" : "5e10983cb182628af48e590a/9d006f1ed361540ecf9d24c807a111770cf9e44f.jpg",
"userId" : ObjectId("5e10983cb182628af48e590a"),
"zoomId" : "5e10983cb182628af48e590a/88a87440a9b7845aa44c72411edddc98ea56f6b9.jpg",
"createdAt" : ISODate("2020-01-05T09:25:52.019+0000"),
"updatedAt" : ISODate("2020-01-05T09:25:52.019+0000"),
"__v" : 0
}
]
}
The error is correct, aggregation output is an Array of objects.
You want to do: (assuming the aggregation returns results)
console.log(account[0]._id)
I want to update Itinirary which is embedded subdocument inside the
packages which itself is a embedded document.I tried using index and
was successful like this :
"$set":{'packages.$.itinerary.0.to': "kausaltar"}
but I don't want to use index like 0,1 in itinerary update.Please can you help me.
My JSON schema is like this :
{
"_id" : ObjectId("5e1ca76b9f96d17c449de177"),
"org_id" : "22222222222",
"packages" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17a"),
"region" : "ppopopop",
"itinerary" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17d"),
"id" : 1,
"from" : "ppopopop",
"to" : "ashinnkn",
"mode" : "4444444444",
"day" : 2,
"duration_hrs" : 3
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17c"),
"id" : 2,
"from" : "44444444444",
"to" : "Faketon2",
"mode" : "4444444444",
"day" : 2,
"duration_hrs" : 3
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17b"),
"id" : 3,
"from" : "55555555555",
"to" : "ashin",
"mode" : "55555555",
"day" : 2,
"duration_hrs" : 3
}
],
"image_url" : "sadfasfsa",
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de178"),
"region" : "bktll",
"itinerary" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de179"),
"id" : 1,
"from" : "mmkkkkm",
"to" : "ashin",
"mode" : "SkkkkA",
"day" : 2,
"duration_hrs" : 3
}
],
"image_url" : "sadfasfsa",
}
]
}
}
I want to update itinerary field inside packages which itself is an embedded document.
And my code is like this :
AgentPackage.update({
"_id" : mongoose.Types.ObjectId("5e1ca76b9f96d17c449de177"),
"packages.region" : "ppopopop",
'packages.itinerary.id': 2,
}, {$set: {'packages.itinerary.$$.from': "test" }}
I am not being able to update.I don't want to use indexing like 0,1 INSIDE query.
Try this :
If you've only one object inside packages with region : "ppopopop", then try this (this should suffice in most cases as you might not have duplicate regions with same name) :
AgentPackage.update({
_id: ObjectId("5e1ca76b9f96d17c449de177"), "packages.region": "ppopopop"
}, { $set: { "packages.$.itinerary.$[item].to": 'kausaltar' } }, {
arrayFilters: [{ 'item.id': 2 }]
})
If you've got multiple objects inside packages with region : "ppopopop", then try this :
AgentPackage.update({
_id: ObjectId("5e1ca76b9f96d17c449de177"), "packages.region": "ppopopop" // Here this "packages.region": "ppopopop" is optional as _id will only bring one document else might be helpful to bring only docs with region: ppopopop right after filter.
}, { $set: { "packages.$[eachPackage].itinerary.$[eachItinerary].to": 'kausaltar' } }, {
arrayFilters: [{ 'eachPackage.region': "ppopopop" }, { 'eachItinerary.id': 2 }]
})
Ref : update-positional-filtered
You can do it with $arrayfilter
db.getCollection("unit").update({_id: ObjectId("5e1ca76b9f96d17c449de177")}, { $set: { "packages.$[t].itinerary.$[d].from": "test" } },
{ arrayFilters: [ { "t.region": "ppopopop" }, {"d.id":15}]})
I have this nested Schema for my courses collections, there is a sessions array in every course and a students array in every session and every student is an object consisting of a property of userName with a value of ObjectId refering to my users collections and another property names status containing some number.
I want to delete an student object from my students array of my session with its _id.
I know it is possible to unwind arrray to get to a single object but I need a neat way like using an objectId to delete an object from database so that we don't have to specify path like directly deleting or modifying that nested subdocument.
This is my course schema:
CourseSchema = new mongoose.Schema({
name:String,
sessions:[
{
date:Date,
students :[{
userName:{
type:mongoose.Schema.Types.ObjectId,
ref :'users'
},
status:Number
}]
}
]
})
You can use the following DELETE route to delete a student from a course session.
router.delete(
"/course/:courseId/session/:sessionId/student/:studentId",
async (req, res) => {
try {
let result = await Course.updateOne(
{ _id: req.params.courseId, "sessions._id": req.params.sessionId },
{
$pull: { "sessions.$.students": { userName: req.params.studentId } }
}
);
res.send(result);
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
}
);
Let's say you have a course like this:
{
"_id" : ObjectId("5de907acdfcef9493cd215a8"),
"name" : "Course 1",
"sessions" : [
{
"date" : ISODate("2019-12-05T16:32:41.998+03:00"),
"_id" : ObjectId("5de907acdfcef9493cd215a9"),
"students" : [
{
"_id" : ObjectId("5de907acdfcef9493cd215ac"),
"userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215ab"),
"userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215aa"),
"userName" : ObjectId("5de8e4ddf74cf254d04f90da"),
"status" : 1
}
]
}
],
"__v" : 0
}
If we want to delete the student with userName with value 5de8e4ddf74cf254d04f90da, we can send a DELETE request to our route using an url like this:
http://localhost/courses/5de907acdfcef9493cd215a8/session/5de907acdfcef9493cd215a9/student/5de8e4ddf74cf254d04f90da
5de907acdfcef9493cd215a8--> courseId
5de907acdfcef9493cd215a9--> sessionId
The response will be like this:
{
"n": 1,
"nModified": 1,
"ok": 1
}
When we look at our course, we see the student is removed:
{
"_id" : ObjectId("5de907acdfcef9493cd215a8"),
"name" : "Course 1",
"sessions" : [
{
"date" : ISODate("2019-12-05T16:32:41.998+03:00"),
"_id" : ObjectId("5de907acdfcef9493cd215a9"),
"students" : [
{
"_id" : ObjectId("5de907acdfcef9493cd215ac"),
"userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215ab"),
"userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
"status" : 1
}
]
}
],
"__v" : 0
}
As we see the student with username with value 5de8e4ddf74cf254d04f90da does not exists anymore in the course session, meaning it is removed.
i have inside my mongoDB collection this document
{
"_id" : ObjectId("5b633025579fac22e74bf3be"),
"FLAGS" : [
{
"toSent" : [
{
"_id" : ObjectId("5b633025579fac22e74bf3c2"),
"phone" : "+84404040404"
},
{
"_id" : ObjectId("5b633025579fac22e74bf3c1"),
"phone" : "+212652253403"
},
{
"_id" : ObjectId("5b633025579fac22e74bf3c0"),
"phone" : "+212123456788"
}
],
"_id" : ObjectId("5b633025579fac22e74bf3bf"),
"action" : "group_p_a"
},
{
"toSent" : [
{
"_id" : ObjectId("5b633031579fac22e74bf3c9"),
"phone" : "+212651077199"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c8"),
"phone" : "+84404040404"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c7"),
"phone" : "+212652253403"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c6"),
"phone" : "+212123456788"
}
],
"_id" : ObjectId("5b633031579fac22e74bf3c5"),
"action" : "group_p_a"
}
],
"time" : ISODate("2018-08-02T16:24:05.747+0000"),
"action_user_phone" : "+212123456788",
"idGroup" : "e534379a-1580-4568-b5ec-6eaf981538d2",
"nomGroup" : "MOH FOR EVER",
"__v" : NumberInt(0)
}
TODO
I need to remove for example this element { "_id" : ObjectId("5b633025579fac22e74bf3c2"), "phone" : "+84404040404"}
WHAT I DID
GroupEvents.update({}, {$pull:{FLAGS:{$elemMatch:{toSent:{phone: "+84404040404"} }}}},function(err,ret){
if(err)
console.log("error"+err);
if(ret)
console.log(ret);
});
It remove all what's inside toSent event if it doesn't match.
Any help please
You need to use $ positional operator instead of $elemMatch here
GroupEvents.update(
{ "Flags.toSent.phone": "+84404040404" },
{ "$pull": { "FLAGS.$.toSent": { "phone": "+84404040404" }}},
)
If you want remove from every element of FLAGS array this you need to use $[] the all positional operator
GroupEvents.update(
{ "Flags.toSent.phone": "+84404040404" },
{ "$pull": { "FLAGS.$[].toSent": { "phone": "+84404040404" }}},
)
I need to change the status to Y for particular comment if i click approved button in UI, My document structure is below.
{
"_id" : ObjectId("5a1fd0ffef39ff11ae353d10"),
"file_name" : "Profile",
"file_type" : "docx",
"created_date" : ISODate("2017-11-28T10:29:10.373Z"),
"updated_date" : ISODate("2017-11-28T12:39:32.148Z"),
"comments" : [
{
"created_date" : ISODate("2017-11-28T13:23:51.472Z"),
"status" : "N",
"comment_text" : "Yes...",
"username" : "Vishnu"
},
{
"created_date" : ISODate("2017-11-28T13:24:15.938Z"),
"status" : "N",
"comment_text" : "Yes...",
"username" : "Vishnu"
},
{
"created_date" : ISODate("2017-11-28T13:28:44.455Z"),
"status" : "N",
"comment_text" : "fsdfdsf",
"username" : "T"
},
{
"created_date" : ISODate("2017-11-28T13:29:22.132Z"),
"status" : "N",
"comment_text" : "fdsfsdf",
"username" : "dasdas"
},
{
"created_date" : ISODate("2017-11-28T13:29:46.247Z"),
"status" : "N",
"comment_text" : "fdgdfgfd",
"username" : "Vishnu T"
}
]
}
I have tried some query which was already in stackover flow like
mongo.filemanager.update(
{ "_id": req.body.id, "comments.comment_text": req.body.comments },
{ "$set": { "comments.$.status": 'Y' } }
)
But status value is not get changing. am using mongoose here.
Kindly help me in this issue.. Thanks In advance
Updated
mongo.filemanager.findOneAndUpdate(
{ "_id": req.body.id, "comments.comment_text": req.body.comments },
{
"$set": { "comments.$.status": 'Y' }
},
function(err,doc) {
if (err) throw err
console.log("Updated Commentstatus")
}
);
Here is the syntax of update in mongoose.
Model.update(conditions, update, options, callback);
So,
$set should be the second paramter,
try
mongo.filemanager.update({ "_id": req.body.id, "comments.comment_text": req.body.comments },{ "$set": { "comments.status": 'Y' } })
Mongoose official Documentation
You can also use findOneAndUpdate,
mongo.filemanager.findOneAndUpdate(
{ "_id": req.body.id, "comments.comment_text": req.body.comments },
{
"$set": { "comments.status": 'Y' }
},
function(err,doc) {
}
);
I've made an example that look like your case, interesting.
You can simulate mongodb terminal online in here for free