insert or update(upsert) in loopback application - node.js

I developed an API using Loopback framework, in that i have to insert or update to a table.
My table looks like below:
userid bbid saved id(PK)
1 5 1000 1
So when next time if(bbid = 5) it should update the above row, if bbid =5 is not there it should insert into the above table.
I tried the following:
app.models.modelname.upsert({
bbid: bb.id,
saved: Saved,
userid: 1
}, function(err, res) {});
EDIT for COMPOSITE ID:
app.models.modelname.upsert({
bbid: vvvv.bbid,
userid: 1,
saved: amountSaved
}, function(err, res) {});
Also gone through Loopback doc it says
upsert - checks if the instance (record) exists, based on the designated
ID property, which must have a unique value; if the instance already exists,
the method updates that instance. Otherwise, it inserts a new instance.
But in my case it should check for bbid not id
But its inserting everytime. Please share your ideas. Thanks in advance
EDIT FOR UPSERT:
My process is as follows:
Fetch from table1 and loop that response and calculate the saved and upsert it into another table(table2 (this is where upsert should happen)). Also the fetching from table1 will happen frequently so suppose consider if is happens 2nd time it should update the already present bbid..

You can use the findOrCreate method as follows:
app.models.modelname({where: {bbid:bb.id} }, {bbid:bb.id, saved: Saved, userid:1}, function(err, instance) {
if (err){
cb(null, err);
}
cb(null, instance);
});

There are two methods in loopback one is simple upsert and second is upsertWithWhere.To insert or update based on where condition you must use upsertWithWhere method upsert only inserts the data.
you are using
app.models.modelname.upsert({bbid:bb.id, saved: Saved, userid:1}
,function(err, res){});
instead use
app.models.modelname.upsertWithWhere({bbid:bb.id, saved: Saved, userid:1}
,function(err, res){});
this will solve your problem.
note: this only updates single instance.If multiple instances are returned in where condition result it will throw an error.

Related

Sending the same PUT request multiple times creates more entries in the database

As far as I know, with PUT one can create a resource if it doesn't exist or it is going to replace the old one with a new one.
I want to create a resource and being able to update it, not create more resources, using Node.js/Express and MongoDB.
So, I wrote this code:
app.put('/entries/:entry_id/type', (req, res) => {
const entry = new Entry (req.body);
entry.save();
res.end();
})
in Postman there is a PUT request, having the url: localhost:5000/entries/2/type
After sending it once, it creates an entry in the dabatase. All good!
But let's try to send the same request again. Now there are 2 entries in the database. I would expect to be one, because the same request was sent.
In the database they have the same data, same schema but they do have an extra field,
"_id":{"$oid":"5e8909e60c606c002axxxxxx"},, which is has the last character different.
Why are there created more entries of the same data while I was expecting to have only one entry in the database?
Mongo automatically creates a default index named _id on every collection when it is created. If you insert a Document into a collection without specifying an _id it will generate a new ObjectId as the _id field.
To get around this you can use findOneAndUpdate with upsert:
Entry.findOneAndUpdate({ entry_id: req.params.entry_id }, { <content> }, { upsert: true })
However this will update the document if it exists already instead of creating a new one. If you further wish to not change the Document at all if it already exists, then you can surround your <content> with $setOnInsert.

mongoosedb expires property not expiring

I've created a Schema which contains this property:
expire: {
type: Date,
default: Date.now,
expires: 60
}
When a new document is created it successfully sets the expire field to the current datetime.
No index is created on the collection.
I subsequently added
model.on('index',function(err){
console.log('index created');
if (err) {
console.log(err);
}
});
Neither logs are occuring.
So I'm assuming that mongoose is not even attempting to create the ttl index on the collection, but I don't see why not. Am I missing a step? am I meant to create the index myself? the mongoose docs seem to imply that mongoose handles creation of the index.
mongoosejs does indeed handle the creation of the index as suspected. In order to find the problem I added an ensureIndexes call as follows:
model.ensureIndexes(function (err) {
console.log('ensure index', err)
})
This then showed that one of the existing indexes (unique email addresses) was failing because of existing documents in the DB which were not unique.
Fixing this problem the above code then works fine. Hope this helps anyone else who runs into problems with mongoose TTL.

Inserting the records in the table if not exists after sequelize.sync({force:true}) is called

I need to add some records to the table if there is no record exists. For now, I have written the logic to add the records in the callback function of the sequelize.sync({force:true}). I have checked whether the table contains atleast one record, and if not, I have inserted the set of records. Is there any other elegent way to obtain this functionality?
I'm reaaaaaly late to this question, but you can use findOrCreate
Like.findOrCreate({
where: {//object containing fields to found
InstagramPostId: inputLike.InstagramPostId,
InstagramUserId: inputLike.InstagramUserId
},
defaults: {//object containing fields and values to apply
postInstagramPostId: inputLike.postInstagramPostId,
userInstagramUserId: inputLike.userInstagramUserId
}
}).error(function(err){//error handling
console.log(err);
}).then(function(){//run your calllback here
console.log("callback!!");
});
Updated 02/07/2021: Use this code: Tested! Run ok.
Like.findOrCreate({
where: {//object containing fields to found
InstagramPostId: inputLike.InstagramPostId,
InstagramUserId: inputLike.InstagramUserId
},
defaults: {//object containing fields and values to apply
postInstagramPostId: inputLike.postInstagramPostId,
userInstagramUserId: inputLike.userInstagramUserId
}
}).then(function(){//run your calllback here
console.log("callback!!");
}).catch(err => {
res.status(500).send("Error -> " + err);
});

Why is Model.save() not working in Sails.js?

Save() giving me error like "Object has no method 'save'"
Country.update({id:req.param('country_id')},model).exec(function(err,cntry){
if(err) return res.json(err);
if(!cntry.image){
cntry.image = 'images/countries/'+filename;
cntry.save(function(err){ console.log(err)});
}
})
Any Idea about how to save model within update query . ??
Assuming you're using Waterline and sails-mongo, the issue here is that update returns an array (because you can update multiple records at once), and you're treating it like a single record. Try:
Country.update({id:req.param('country_id')},model).exec(function(err,cntry){
if(err) return res.json(err);
if(cntry.length === 0) {return res.notFound();}
if(!cntry[0].image){
cntry[0].image = 'images/countries/'+filename;
cntry[0].save(function(err){ console.log(err)});
}
});
This seems to me an odd bit of code, though; why not just check for the presence of image in model before doing Country.update and alter model (or a copy thereof) accordingly? That would save you an extra database call.
When using mongoose (3.8) to update the database directly the callback function receives 3 parameters, none of then is a mongoose object of the defined model. The parameters are:
err is the error if any occurred
numberAffected is the count of updated documents Mongo reported
rawResponse is the full response from Mongo
The right way is, first you fetch and then change the data:
Country.findOne({id: req.param('country_id')}, function (err, country) {
// do changes
})
Or using the update method, the way you intended:
Country.update({id: req.param('country_id'), image: {$exists: false}}, {image: newValue}, callback)

Issue with updating new row by using the mongodb driver

How can I add a new row with the update operation
I am using following code
statuscollection.update({
id: record.id
}, {
id: record.id,
ip: value
}, {
upsert: true
}, function (err, result) {
console.log(err);
if (!err) {
return context.sendJson([], 404);
}
});
While calling this first one i will add the row
id: record.id
Then id:value then i have to add id:ggh
How can i add every new row by calling this function for each document I need to insert
By the structure of your code you are probably missing a few concepts.
You are using update in a case where you probably do not need to.
You seem to be providing an id field when the primary key for MongoDB would be _id. If that is what you mean.
If you are intending to add a new document on every call then you probably should be using insert. Your use of update with upsert has an intended usage of matching a document with the query criteria, if the document exists update the fields as specified, if not then insert a new document with the fields specified.
Unless that actually is your goal then insert is most certainly what you need. In that case you are likely to rely on the value of _id being populated automatically or by supplying your own unique value yourself. Unless you specifically want another field as an identifier that is not unique then you will likely want to be using the _id field as described before.

Resources