Node.js update element in MongoDB - javascript

I have the following Mongoose schema and model:
var deviceSchema = new Schema({
deviceId:String,
deviceName:String,
devicePlace:String,
socket : [{number: Number,name:String, state : Boolean, current: Number, image:Number,locked:Boolean,reserved:Boolean}]
});
I already have a device in my database with four sockets.
Here example!
This is original data.
{
"_id" : ObjectId("5626569006bc3da468bafe93"),
"deviceId" : "0013A20040B5769A",
"deviceName" : "device",
"devicePlace" : "place",
"__v" : 0,
"socket" : [
{
"_id" : ObjectId("5628bd83570be84e28879e2d"),
"number" : 0,
"name" : "name"
"state" : true,
"current" : 0
"image" : 0,
"locked" : false,
"reserved" : false,
}, ...
]
}
and I received data from client for update.
{
"_id" : ObjectId("5626569006bc3da468bafe93"),
"deviceId" : "0013A20040B5769A",
"__v" : 0,
"socket" : [
{
"_id" : ObjectId("5628bd83570be84e28879e2d"),
"number" : 0,
"name" : "new name!!!!!"
"state" : true,
"current" : 0
}, ...
]
}
Now I'm trying to update a specific socket's name in the database with the following command:
device.update({deviceId: newData.deviceId, "socket.number": newData.number}, {$set: {"socket.$.name": newData.name}})
newData is object that extracted from socket array in received data.
I want to just update first socket's name.
or if possible, I want to update every socket's name as received socket array.
But this does not seem to be working, but I get no error. Can someone pin point what I'm doing wrong?

Add the callback to the update statement to see the error trace.
device.update({deviceId:newData.deviceId,'socket.number':newData.number}
,{$set: {"socket.$.name" : newData.name}}
,function(error,updatedDevice){
if(error) throw error;
// or : console.log("update error",error.message);
})

Related

How do I access and update nested Mongoose documents

I have a mongoose document that is a User. Each user has arrays or words e.g. nouns. I want to be able to update the fields of the words e.g. add a +1 to the frequency or change the status number. I can access the whole array but not the individual items in the array. Also i want to be able to display the items in the array based on their fields e.g. only display those with frequency of 3 or more etc...
I have tried lots of different things but I'm just not getting it. I keep getting back error messages that findOneAndUpdate is not a function, or 'undefined' when I try to access and update documents.
{
"_id" : ObjectId("5f7d8490c1842471c6bcea42"),
"username" : "eric#mail.com",
"nouns" : [
{
"_id" : ObjectId("5f7d849cc1842471c6bcea43"),
"word" : "die Sonne",
"timeStamp" : ISODate("2020-10-07T09:04:28.436Z"),
"frequency" : 0,
"status" : 0
},
{
"_id" : ObjectId("5f7d84a8c1842471c6bcea45"),
"word" : "das Wetter",
"timeStamp" : ISODate("2020-10-07T09:04:40.940Z"),
"frequency" : 0,
"status" : 0
},
{
"_id" : ObjectId("5f7d84afc1842471c6bcea47"),
"word" : "der Apfel",
"timeStamp" : ISODate("2020-10-07T09:04:47.403Z"),
"frequency" : 0,
"status" : 0
},
{
"_id" : ObjectId("5f7d84b9c1842471c6bcea49"),
"word" : "das Maedchen",
"timeStamp" : ISODate("2020-10-07T09:04:57.388Z"),
"frequency" : 0,
"status" : 0
},
{
"_id" : ObjectId("5f7d84c8c1842471c6bcea4b"),
"word" : "das Auto",
"timeStamp" : ISODate("2020-10-07T09:05:12.036Z"),
"frequency" : 0,
"status" : 0
}
],
"verbs" : [],
"adjectives" : [],
"others" : [],
"salt" : "*****",
"hash" : "*****",
"__v" : 5
}
figured it out after hours
const ObjectId = require('mongodb').objectID
db.collections.users.updateOne(
{},
{$set: {"nouns.$[element].status": 3}},
{multi: true,
arrayFilters: [{"element._id":
ObjectId(req.body.inputId)}]}
);

MongoDB update function doesn't work with Mongoose

I'm trying to insert a new field into a document in MongoDB, but the database has no changes after my query.
This is the single element of my database:
{
"_id" : ObjectId("5a9f5f4bb9ba6117b5551f7d"),
"userId" : "user123",
"name" : "Device zm3",
"category" : [
"pm10",
"pm25",
"temperature"
],
"__v" : 0}
I want to have something like this:
{
"_id" : ObjectId("5a9f5f4bb9ba6117b5551f7d"),
"userId" : "user123",
"name" : "Device zm3",
"category" : [
"pm10",
"pm25",
"temperature"
],
"data": 5
"__v" : 0}
I use this query:
Device.update({
'userId': 'user123'
}, {
$set: {
'data': 5
}
}, {
upsert: true,
}
I was trying with fields witch already exists in database such as "name" or "category", and in this case solution works.
If you are going to add a field with Mongoose, it should also be in your Mongoose schema. So you would have to add "data" to your Device schema if you want to use Mongoose. That's why fields already in the object/schema (like "name" or "category") work but new ones don't.

Mongoose, query a collection with a set of ObjectID

I'm creating an api with node.js, express and mongoose. I'm pretty new to mongosse and I am wondering if there exists a better way to do what I want.
I have two collections: users and expenses.
User example:
{
"_id" : ObjectId("59c4bc6a39d9992d6407427e"),
"firstName" : "John",
"lastName" : "Doe",
"name" : "JohnD",
"password" : "xxxxx",
"__v" : 26,
"budget" : 400,
"saving" : 300,
"wage" : 1340,
"expenses" : [
ObjectId("59cd076544fa3e64ec32c7e3"),
ObjectId("59cd07f0ed7bd2192cab72bd"),
ObjectId("59cd0a78e19060451059dce7"),
ObjectId("59cd0b24e19060451059dce8"),
ObjectId("59cd0b8fe19060451059dce9"),
ObjectId("59cdf34be19060451059dcf4"),
ObjectId("59cdf3c1e19060451059dcf5"),
ObjectId("59cdf417e19060451059dcf6"),
ObjectId("59cdf446e19060451059dcf7"),
ObjectId("59cdf46ee19060451059dcf8"),
ObjectId("59cdf4bce19060451059dcf9"),
ObjectId("59cdf6dee19060451059dcfa"),
ObjectId("59cdf6f5e19060451059dcfb"),
ObjectId("59cdf768e19060451059dcfc"),
ObjectId("59cdf798e19060451059dcfd"),
ObjectId("59cdf806e19060451059dcfe")
]
}
Expense example:
{
"_id" : ObjectId("59cd07f0ed7bd2192cab72bd"),
"name" : "shopping",
"price" : 100,
"date" : 1506607687013,
"repetition" : 0,
"__v" : 0
}
{
"_id" : ObjectId("59cd0a78e19060451059dce7"),
"name" : "gazoil",
"price" : 50,
"date" : 1506607687013,
"repetition" : 0,
"__v" : 0
}
I want to do a function which takes a user and return all of its expenses. Am I forced to loop through all objectId in user.expenses or there is a proper way to do that directly with mongoose ?
Mongoose has a method for doing what you are willing to do: Query Population
You need to set your schema right and push the refs to the children, then use the populate() method:
const user = await User
.findOne({ _id: 'yourObjId' })
.populate('expenses')
.exec()
console.log(user.stories)
You can use $lookup/aggregate
Check some examples on this answer which seem to explain your use case.
Mongodb, aggregate query with $lookup

Handling Monggose schema change handling from string to string Array

My current doc is like this
{
"_id" : ObjectId("55ece69df332eb0000d34e12"),
"parent" : "P1",
"hierarchy" : {},
"hidden" : false,
"type" : "xyz",
"name" : "Mike",
"code" : "M110",
"date" : ISODate("2015-09-07T01:21:33.965Z"),
"__v" : 3,
"job_id" : "ca50fdf0-6904-11e6-b9af-1b0ea5d7f792"
}
now i want to have job_id as array instead. So i changed the field type to array in model schema. Now when I try to update the existing docs with some changes.
Document before saving looks like this
{
"_id" : ObjectId("55ece69df332eb0000d34e12"),
"parent" : "P1",
"hierarchy" : {},
"hidden" : false,
"type" : "xyz",
"name" : "Mike",
"code" : "M110",
"date" : ISODate("2015-09-07T01:21:33.965Z"),
"__v" : 3,
"job_id" : ["ca50fdf0-6904-11e6-b9af-1b0ea5d7f792",
"f1f04a95-42fa-41e5-a2c6-89c52c9c63f2"
]
}
so when i call model.save() method i'm getting following error:
{ [MongoError: The field 'job_id' must be an array but is of type String in document {_id: ObjectId('55ece69df332eb0000d34e12')}]
name: 'MongoError',
code: 16837,
err: 'The field \'job_id\' must be an array but is of type String in document {_id: ObjectId(\'55ece69df332eb0000d34e12\')}' }
What is the best way to handle this??

Node.js update elements in MongoDB

I have the following Mongoose schema and model:
var deviceSchema = new Schema({
deviceId:String,
deviceName:String,
devicePlace:String,
socket : [{number: Number,name:String, state : Boolean, current: Number, image:Number,locked:Boolean,reserved:Boolean}]
});
I already have a device in my database with four sockets.
Here example!
This is original data.
{
"_id" : ObjectId("5626569006bc3da468bafe93"),
"deviceId" : "0013A20040B5769A",
"deviceName" : "device",
"devicePlace" : "place",
"__v" : 0,
"socket" : [
{
"_id" : ObjectId("5628bd83570be84e28879e2d"),
"number" : 0,
"name" : "name"
"state" : true,
"current" : 0
"image" : 0,
"locked" : false,
"reserved" : false,
}, ...
]
}
and I received data from client for update.
{
"_id" : ObjectId("5626569006bc3da468bafe93"),
"deviceId" : "0013A20040B5769A",
"__v" : 0,
"socket" : [
{
"_id" : ObjectId("5628bd83570be84e28879e2d"),
"number" : 0,
"name" : "new name!!!!!"
"state" : true,
"current" : 0
}, ...
]
}
Now I'm trying to update a specific socket's name in the database with the following command:
device.update({deviceId: newData.deviceId, "socket.number": newData.number}, {$set: {"socket.$.name": newData.name}})
newData is object that extracted from socket array in received data.
I want to just update first socket's name.
or if possible, I want to update every socket's name as received socket array.
But this does not seem to be working, but I get no error. Can someone pin point what I'm doing wrong?

Categories

Resources