mongoose/javascript: Can't update collection in Mongodb - javascript

This is my db schema
let couponId = Schema({
RestaurantId: { type: String },
RestaurantName: { type: String },
RestaurantLocation: { type: String },
AssignedTo: Schema.Types.Mixed,
CouponValue: { type: [String] }
});
I want to update the AssignedTo field with a value of array of objects with a dynamic key and a value. I am performing this query
CouponId.findOne({
"RestaurantId": resId
}, (err, restaurant) => {
value.push({
[userNumber]: restaurant.CouponValue[0]
});
console.log(value);
restaurant.update({
"RestaurantId": resId
}, {
$set: {
"AssignedTo": value
}
}, function(err) {
if (err) {
console.log(err);
} else {
console.log("updated");
}
});
});
The query, when executed, is giving the result of updated in console but its not getting updated in db. If this query is converted to MongoShell query and executed, it gives the result and collection is getting updated, where mongoShell query i am running is
db.couponids.update({"RestaurantId" : "1234"},{$set:{"AssignedTo":[{"1234":"2345"}]}});
Where am i going wrong?

restaurant is the output from the first collection and doesn't have any update function in it... So, You need to keep the same collection name from which you have done findOne
CouponId.update({
"RestaurantId": resId
}, {
$set: {
"AssignedTo": value
}
}, function(err) {
if (err) {
console.log(err);
} else {
console.log("updated");
}
});

Related

Update mongo collection with values from a javascript map

I have a collection that looks like this
[
{
"project":"example1",
"stores":[
{
"id":"10"
"name":"aa",
"members":2
}
]
},
{
"project":"example2",
"stores":[
{
"id":"14"
"name":"bb",
"members":13
},
{
"id":"15"
"name":"cc",
"members":9
}
]
}
]
I would like to update the field members of the stores array taking getting the new values from a Map like for example this one
0:{"10" => 201}
1:{"15" => 179}
The expected result is:
[
{
"_id":"61",
"stores":[
{
"id":"10"
"name":"aa",
"members":201
}
]
},
{
"_id":"62",
"stores":[
{
"id":"14"
"name":"bb",
"members":13
},
{
"id":"15"
"name":"cc",
"members":179
}
]
}
]
What are the options to achieve this using javascript/typescript?
In the end, I resolved by updating the original database entity object with the values in the map, then I have generated a bulk query.
for (let p of projects) {
for(let s of p.stores) {
if(storeUserCount.has(s.id)){
s.members = storeUserCount.get(s.id);
}
};
bulkQueryList.push({
updateOne: {
"filter": { "_id": p._id },
"update": { "$set": {"stores": p.stores} }
}});
};
await myMongooseProjectEntity.bulkWrite(bulkQueryList);
You can use update() function of Mongoes model to update your expected document.
Try following one:
const keyValArray= [{"10": 201},{"15":"179"}];
db.collectionName.update({_id: givenId},
{ $push: { "stores": {$each: keyValArray} }},
function(err, result) {
if(err) {
// return error
}
//return success
}
});

How to access array elements that are defined in another array of Mongoose scheme object Array?

This is the User schema in mongoose:
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
},
name: {
type: String,
required: true,
},
Addtasks: [
{
topic: String,
words: Number,
keywords: String,
website: String,
otherdetails: String,
exampleRadios: String,
deadline: Date,
Date: String,
fileName: String,
Bigpaths: [],
},
],
});
module.exports = mongoose.model('User', userSchema);
I want to use/access the Bigpaths array, which is defined inside the Addtasks array, which is defined in User. Data is already are there in mongoDB, which I have inserted via UI page. I am trying the following code but I am getting this error in console:
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
// ...
}
)
as
TypeError: Cannot read property 'Bigpaths' of undefined
at \Desktop\grumpytext\routes\index.js:99:71
Code:
const { files } = req;
User.findOne({ email: req.user.email }, function (error, data) {
if (error) {
console.log('Three');
} else if (data) {
if (Object.keys(data.Addtasks).length > 1) {
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
files.forEach((currentElement) => {
if (element.name == currentElement.filename) {
files.pull(currentElement.filename);
}
});
}
);
}
}
});
How to resolve this error or how to access all the elements of Bigpaths array so that I can iterate it with forEach loop?
I'm not sure here, but I think you need to populate Addtasks prior to manipulating it:
const files = req.files;
User.findOne({email:req.user.email}).populate('Addtasks').exec((error, data) => {
if (error) {
console.log("Three");
}
else
{
if(data)
{
if(Object.keys(data.Addtasks).length > 1)
{
console.log("Addtasks count: " + Object.keys(data.Addtasks).length);
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(element => {
files.forEach(currentElement => {
if(element.name == currentElement.filename)
{
files.pull(currentElement.filename);
}
})
});
}
}
}
});
Please notice the log console.log("Addtasks count: " + Object.keys(data.Addtasks).length); - in case the solution does not work, I advise to add some prints, especially to check if the count of elements is as expected or properties within an object are fine.

Increment value in update query mongoDB

I am trying to add two values in a mongoose function.
This the function im using:
Equipa.findOne({ '_id': req.params.equipaID }, function (error, equipa) {
if (error) {
return (error);
}
if (util.isNullOrUndefined(equipa)) {
return res.status(204).end()
}
console.log(equipa.distanciaTotal + "------" + req.body.distanciaPercorrida),
{ total : {$add[equipa.distanciaTotal,req.body.distanciaPercorrida]}},
console.log(total)
});
The values in equipa.distanciaTotal and req.body.distanciaPercorrida are correct, and so is the Equipa found by Equipa.findOne.
I think it will be fine updating the document, but I simply cannot add the two values.
You can use $inc to increment the existing value
Equipa.findOneAndUpdate(
{ '_id': req.params.equipaID },
{ '$inc': {
distanciaTotal: req.body.distanciaPercorrida }
}
)
You could either use $inc
Equipa.findOneAndUpdate(
{ '_id': req.params.equipaID },
{ $inc: { distanciaTotal: req.body.distanciaPercorrida } }
);
Or save the document after updating it
Equipa.findOne({ '_id': req.params.equipaID }, (err, equipa) => {
equipa.distanciaTotal += req.body.distanciaPercorrida;
equipa.save();
});

How to append a data to an object property in mongodb

I want to send request to a mongodb database.
For example I have this object:
{
id:"1",
requestType : {
"api1" : {count:12,firstTime:12},
"api2" : {count:6,firstTime:18}
}
}
after getting data by "id" I want to append another row to "requestType" for example "api3":{count:56,firstTime:11}.
my expected object is:
{
id:"1",
requestType : {
"api1" : {count:12,firstTime:12},
"api2" : {count:6,firstTime:18},
"api3":{count:56,firstTime:11}
}
}
currently I'm using this query by mongoose:
apiAttemptsModel.findOneAndUpdate(query, {
$set: {
requestType : {"api3":{count:56,firstTime:11}}
}
}, {upsert: true, new: true}, function (err, row) {
if (err) {
callback('err is ' + err)
} else {
callback(row);
}
});
But this code will exchange old requestType object with the new one.
Try this:
apiAttemptsModel.findOneAndUpdate(query, {
$set: {
"requestType.api3" : {count:56, firstTime:11}
}
}, {upsert: true, new: true}, function (err, row) {
if (err) {
callback('err is ' + err)
} else {
callback(row);
}
});
By the way, this is not the proper way to use callbacks.
callbacks in node are usually called with the following signature:
function(error, data) -
thus when calling callback(row); a user of this method might expect an error there, much like you did with the callback function on line 5.
The first argument is usually null when no error has occurred.
In addition, calling callback('err is ' + err) will only keep the error's message and discard its stack trace, because the error is "converted" to a string.
I'd convert your code to:
apiAttemptsModel.findOneAndUpdate(query, {
$set: {
"requestType.api3" : {count:56, firstTime:11}
}
}, {upsert: true, new: true}, function (err, row) {
if (err) {
callback(err)
} else {
callback(null, row);
}
});
Set upset to false. This will update the document, but will not create it if it does not already exist.
https://docs.mongodb.com/manual/reference/method/db.collection.update/

Mongodb - Search by id and embedded array value

Im trying to write a function that will search for an object by ID and whether or not a value is contained in an embedded array within the object.
{
"_id" : ObjectId("569bea91c0e1fee4063527ac"),
"user" : ObjectId("568c65174fee132c36e199dd"),
"votes" : 9,
"image" : "./modules/deals/client/img/uploads/1546f914dba7e1732ea853cd70d79148.jpg",
"price" : "12.95",
"retailer" : "argos.co.uk",
"voters" : [{
"user" : ObjectId("568c65174fee132c36e199dd"),
},
{
"user" : ObjectId("568c65174fee132c36e199dd"),
},
{
"user" : ObjectId("568c65174fee132c36e199dd"),
}]
I would like to search by the _id and the voters.user.
I believe i need to finish this function correctly
exports.dealByIdAndVoter = function(req, res) {
Deal.count({
$where: function () {
}
},
function(err, dealByIdAndVoter) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
console.log(dealByIdAndVoter);
var data = {};
data.count = dealByIdAndVoter;
res.json(data);
}
});
};
If you do not need to use the $where function, you can construct the query with the $or operator in this manner:
Deal
.find({
$or: [
// Match by _id
{ _id: req.id },
// Match by any user in the 'voters' array with a matching 'user' field.
{ 'voters.$.user': req.id }
]
})
.count(function(err, count) {
// Handle error here
res.json(count);
});

Categories

Resources