How to autoIncrement id's and post to mongodb using node js - node.js

I want to increment id's automatically in the mongoDB while posting the data. I am able to attach date for the req.body. How to attach ids with auto incrementation?
This is my post call:
router.post('/addVisualization', function (req, res, next) {
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db(dbName);
req.body.dateOfEntry = new Date();
function getNextSequence(id) {
var ret = db.counters.findAndModify(
{
query: { _id: id },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
dbo.collection("visualization").insertOne(req.body, function (err, resDB) {
if (err) {
throw err;
res.status(401);
res.send({
"status": 401,
"message": "Some error happened"
});
}
else {
console.log("1 document inserted");
res.status(201)
res.send({
"body": req.body,
"status": 201,
"message": "visualization has been added"
});
}
});
db.close();
});
});

Try out the below code to auto increment id's in mongoDB.
router.post('/addVisualization', function (req, res, next) {
MongoClient.connect(url, {
useNewUrlParser: true
}, function (err, db) {
if (err) throw err;
var dbo = db.db(dbName);
req.body.dateOfEntry = new Date();
req.body.isDeleted = "false";
var countRow;
var sequenceDocument = dbo.collection("counterVisualization").findOneAndUpdate({
_id: "tid"
}, {
$inc: {
sequence_value: 1
}
}, {
new: true
});
dbo.collection("counterVisualization").find({
_id: "tid"
}).toArray(function (err, result1) {
if (err) {
throw err;
} else {
countRow = result1[0].sequence_value;
req.body["_id"] = countRow;
dbo.collection("visualization").insertOne(req.body, function (err, resDB) {
if (err) {
throw err;
res.status(401);
res.send({
"status": 401,
"message": "Some error happened"
});
} else {
console.log("1 document inserted");
res.status(201)
res.send({
"body": req.body,
"status": 201,
"message": "visualization has been added"
});
}
});
}
});
});
});

In mongo db you don't have a auto increment ids as mysql or oracle, Please take a look at this tutorial for how to do it out of the box.

Use a separate counters collection to track the last id of the sequence.
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
db.counters.insert(
{
_id: "productid",
seq: 0
}
)
Create a getNextSequence function that accepts a name of the sequence.
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true,
upsert : true // Creates a new document if no documents match the query
}
);
return ret.seq;
}
Use this getNextSequence() function during insert.
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Mr. X",
// ... more fields
}
)
db.products.insert(
{
_id: getNextSequence("productid"),
name: "Mr. Y",
// ... more fields
}
)

Related

why my updateOne mongodb does not return anything?

I have this code:
MongoClient.connect(config.mongoURL, {useNewUrlParser: true}, (err, db)=> {
if (err) {
console.log("Err", err)
cb(-1)
}
else {
var con = db.db('englishAcademy')
try {
con.collection("sound").updateOne({"_id": new ObjectID(sndId)}, {
$set: {
"snd_title": info.snd_title,
"snd_type": info.snd_type,
"snd_url": info.snd_url,
"snd_lsnId": info.snd_lsnId,
"snd_lvlId": info.snd_lvlId,
"snd_order": info.snd_order
}
}), (err, doc) => {
console.log("result")
if (err) {
console.log(err)
cb(-1)
}
else {
console.log(doc)
let result = 'row affected'
cb(doc)
}
}
}
catch (e) {
console.log(e)
}
}
})
could anyone please tell me what is wrong with my code?the updateOne function does not return anything.but my mongo database gets updated.
EDIT :
I have done this so far and it did not worked.could anyone please help?I used assert no success.I used new :true, no success.I used finde and update ,no success
let infor = {
"adm_name": info.adm_name,
"adm_username": info.adm_username,
"adm_password": info.adm_password
}
con.collection("admins").findOneAndUpdate({"_id": new ObjectID(admId)}, {
$set: infor
},{new:true} ), (err , result) => {
console.log("result")
if (err) {
console.log(err)
assert.equal(err, null);
cb(-1)
}
else {
let result = 'row affected'
assert.equal(1, result.result.n);
}
set new: true
MongoClient.connect(config.mongoURL, {useNewUrlParser: true}, (err, db)=> {
if (err) {
console.log("Err", err)
cb(-1)
}
else {
var con = db.db('englishAcademy')
try {
con.collection("sound").updateOne({"_id": new ObjectID(sndId)}, {
$set: {
"snd_title": info.snd_title,
"snd_type": info.snd_type,
"snd_url": info.snd_url,
"snd_lsnId": info.snd_lsnId,
"snd_lvlId": info.snd_lvlId,
"snd_order": info.snd_order
},{new: true}
}), (err, doc) => {
console.log("result")
if (err) {
console.log(err)
cb(-1)
}
else {
console.log(doc)
let result = 'row affected'
cb(doc)
}
}
}
catch (e) {
console.log(e)
}
}
})
Try this way ..
collection.findOneAndUpdate(
{"_id": new ObjectID(sndId)},
$set: yourData },
{ new: true },
function (err, documents) {
res.send({ error: err, result: documents });
}
);
Now you can return newData in cb.

node.js | Redis cache loading old data

I am trying to setup a mongo, node and redis server and all is working well other than the Redis cache which seemingly loads the older data.
Taking Redis out and using pure Mongo returns the right data, and if I click submit again it will load the data from the previous submission, so I know the cache and Mongo is updating fine.
This is the current code I have for updating the user using Mongo and Redis...
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, {
$set: {
"firstName": newUser.firstName,
"lastName": newUser.lastName,
"email": newUser.email
}
}, (err, doc) => {
if (err) { throw new Error(err); }
else if (!doc) { callback('No user with that ID to update cache.') }
else {
redis.set(id, JSON.stringify(doc), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}
And this is the redis and Mongo to return the user information...
userById: async (redis, id, callback) => {
redis.get(id, async (err, reply) => {
if (err) {
callback(null); throw new Error(err);
} else if (reply) {
callback(JSON.parse(reply));
} else {
await User.findById(id, (err, doc) => {
if (err || !doc) { callback(null); throw new Error(err); }
else {
redis.set(id, JSON.stringify(doc), () => {
callback(doc);
})
}
})
}
})
}
I have found out it's something to do with the doc containing the old information in the updateUserById
The issue was inside of the update method.
When the doc was being passed, it was being passed the old data not the new data. To counter act this I used the newUser which was passed into the method.
Here is the updated code:
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, newUser, (err) => {
if (err) { throw new Error(err); }
else {
redis.set(id, JSON.stringify(newUser), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}
Using new option can be useful to return new document.
Mongo return old document by default after update.
To return new document mongo option new may be useful
usage: Model.findByIdAndUpdate(id, update, {new: true});
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, {
$set: {
"firstName": newUser.firstName,
"lastName": newUser.lastName,
"email": newUser.email
}
},{ new : true }, (err, doc) => {
if (err) { throw new Error(err); }
else if (!doc) { callback('No user with that ID to update cache.') }
else {
redis.set(id, JSON.stringify(doc), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}

How to delete Element In MongoDB property's array with MongooseJS?

I cannot remove an element inside of an array that is a property of a MongoDB Model.
Please remember this is a NodeJS module mongooseJS and not the real MongoDB so functionalities are not the same..
GOAL: Delete an object from the statusLiked array. | I have also confirmed that the value of status.id is correct.
Model:
Const userSchema = new mongoose.Schema({
myStatus: Array,
statusLiked: Array,
)};
Delete:
1. Deletes the status(works). 2. Delete the status from User.statusLiked(no work).
exports.deleteStatus = (req, res, next) => {
var CurrentPost = req.body.statusid; // sends in the status.id
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
// vvvv this vvv
User.update( {id: req.user.id}, { $pullAll: {_id: CurrentPost }, function(err) { console.log('error: '+err) } });
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
};
What happens: The specific status(object) is deleted from the database. But the status still remains in the User.statusLiked array.
What I want to happen: Status to be deleted from the User.statusLiked array and the status to be deleted from the database. Then, reload the page and display a notification.
I got it to work somehow. Working code:
exports.deleteStatus = (req, res, next) => {
var CurrUser = req.body.userid;
var CurrentPost = req.body.post;
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
console.log('meeee'+CurrentPost+'user: ' +CurrUser);
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
User.update(
{ _id: new ObjectId(CurrUser)},
{ $pull: { myStatus : { _id : new ObjectId(CurrentPost) } } },
{ safe: true },
function (err, obj) {
console.log(err || obj);
});
};

MongoDB Bulk Insert Ignore Duplicate

I've Googled around and can't find any solid information on how to ignore duplicate errors when using bulk insert.
Here's the code I'm currently using:
MongoClient.connect(mongoURL, function(err, db) {
if(err) console.err(err)
let col = db.collection('user_ids')
let batch = col.initializeUnorderedBulkOp()
ids.forEach(function(id) {
batch.insert({ userid: id, used: false, group: argv.groupID })
})
batch.execute(function(err, result) {
if(err) {
console.error(new Error(err))
db.close()
}
// Do some work
db.close()
})
})
Is it possible? I've tried adding {continueOnError: true, safe: true} to bulk.insert(...) but that didn't work.
Any ideas?
An alternative is to use bulk.find().upsert().replaceOne() instead:
MongoClient.connect(mongoURL, function(err, db) {
if(err) console.err(err)
let col = db.collection('user_ids')
let batch = col.initializeUnorderedBulkOp()
ids.forEach(function(id) {
batch.find({ userid: id }).upsert().replaceOne({
userid: id,
used: false,
group: argv.groupID
});
});
batch.execute(function(err, result) {
if(err) {
console.error(new Error(err))
db.close()
}
// Do some work
db.close()
});
});
With the above, if a document matches the query { userid: id } it will be replaced with the new document, otherwise it will be created hence there are No duplicate key errors thrown.
For MongoDB server versions 3.2+, use bulkWrite as:
MongoClient.connect(mongoURL, function(err, db) {
if(err) console.err(err)
let col = db.collection('user_ids')
let ops = []
let counter = 0
ids.forEach(function(id) {
ops.push({
"replaceOne": {
"filter": { "userid": id },
"replacement": {
userid: id,
used: false,
group: argv.groupID
},
"upsert": true
}
})
counter++
if (counter % 500 === 0) {
col.bulkWrite(ops, function(err, r) {
// do something with result
db.close()
})
ops = []
}
})
if (counter % 500 !== 0) {
col.bulkWrite(ops, function(err, r) {
// do something with result
db.close()
}
}
})

How to use findOneAndUpdate in MongoDB in Node

Say previously I had inserted a document into a mongo collection.
MongoClient.connect(url, function(err,db){
if(err) {throw err;}
else {
document = {action: "alert",
protocol: "udp",
port: "80",
_id: "12" }
var collection = db.collection("connections");
collection.insertOne(document, function(err,result){
if (err) {throw err;}
else {
console.log("Successful")
db.close();
}
}
}
Now I want to update the protocol field. What I have with no luck so far is
MongoClient.connect(url, function(err,db){
if (err) { throw err; }
else {
var collection = db.collection("connections");
collection.findOneAndUpdate({_id: "12"}, {$set: {protocol: "http"}}, {new: true}, function(err,doc) {
if (err) { throw err; }
else { console.log("Updated"); }
});
}
});
Am I passing the wrong parameters to the findOneAndUpdate method? I connect to the database correctly.
I think you should try
MongoClient.connect(url, function(err,db){
if (err) { throw err; }
else {
var collection = db.collection("connections");
collection.findOneAndUpdate({_id: "12"}, {$set: {protocol: "http"}}, {upsert: true}, function(err,doc) {
if (err) { throw err; }
else { console.log("Updated"); }
});
}
});
If "upsert" set to true, creates a new document when no document matches the query criteria.
=== Aug 2021
Here is an example of using findOneAndUpdate and getting back the updated document:
With the release of v4 of the node.js client, it seems the old solution of returnOriginal: false (which was awful anyway) is no longer the correct answer.
To see the list of available options for the node.js findOneAndUpdate method: https://mongodb.github.io/node-mongodb-native/4.0/interfaces/findoneandupdateoptions.html
But in short, this should work:
const doc = await <Collection>.findOneAndUpdate(
{ ... search },
{
$set: {
field1: 'value 1',
field2: ['value 2'],
etc.
},
},
{
upsert: true,
returnDocument: 'after', // this is new !
}
)
your third {new: true} argument is not valid
MongoClient.connect(url, function(err,db){
if (err) { throw err; }
else {
var collection = db.collection("connections");
collection.findOneAndUpdate({"_id": "12"}, {$set: {"protocol": "http"}}, function(err,doc) {
if (err) { throw err; }
else { console.log("Updated"); }
});
}
});
Here to update the record,it is not needed to use {upsert: true} and {new: true}. This solution works better.Try it once and suggest me if any errors in the code.
insert the update document if nothing matches the filter then use upsert.
MongoClient.connect(url, function(err,db){
if (err) { throw err; }
else {
var collection = db.collection("connections");
collection.findOneAndUpdate({_id: "12"}, {protocol: "http"}, {new: true}, function(err,doc) {
if (err) { throw err; }
else { console.log("Updated"); }
});
}
});

Resources