MongoDB update function doesn't work with Mongoose - javascript

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.

Related

Meteor collection find and update value within object in subarray

I'm having some trouble determining how to find a document within a collection, and a value within an object in a subarray of that document — and then update a value within an object in that array.
I need to do the following:
find by _id
find object in ratings array that matches the user + post keys
update the report value within that object
For example, the documents in my collection are set up like below.
{
"_id" : "mz32AcxhgBLoviRWs",
"ratings" : [
{
"user" : "mz32AcxhgBLoviRWs",
"post" : "SMbR6s6SaSfsFn5Bv",
"postTitle" : "fdsfasdf",
"date" : "2017-09-27",
"rating" : "4",
"review" : "sdfa",
"report" : "a report"
},
{
"user" : "mz32AcxhgBLoviRWs",
"post" : "iZbjMCFR3cDNMo57W",
"postTitle" : "today",
"date" : "2017-09-27",
"rating" : "4",
"review" : "sdfa",
"report" : "some report"
}
]
}
It seems that you want just one update, not three separated queries.
Collection.update({
_id: <id>,
ratings: {
$elemMatch: {
user: <user>,
post: <post>
}
}
}, {
$set: {
'ratings.$.report': <report>
}
});
Documentation: $elemMatch, <array>.$.

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 element 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?
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);
})

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