Node.js MongoDB Upsert update - node.js

I'm writing a little application which scores keywords. So if "beirut" and "education" get entered in, if they haven't been seen before, I want to create a mongo entry, and give them a score of 1. If they have, I want to increment their score by one. I'm trying to do this with one update command, but I think I might be doing it wrong.
Ranking is the object representing the database
"key" is the keyword
rankingdb.update(
{keyword:key},
{keyword:key, {$inc:{score:1}}},
{upsert:true, safe:false},
function(err, data) {
if (err) {
console.log(err);
}
else {
console.log("score succeeded");
}
}
);
SyntaxError: Unexpected token {
Can you not create a brand new document with an increment?

Your general approach is right, but as the error message suggests, you've got a syntax problem in your code.
Try this instead:
rankingdb.update(
{keyword: key},
{$inc: {score: 1}},
{upsert: true, safe: false},
function(err,data){
if (err){
console.log(err);
}else{
console.log("score succeded");
}
}
);
When an upsert needs to create a new object it combines the fields from the selector (first parameter) and the update object (second parameter) when creating the object so you don't need to include the keyword field in both.
Note that update() is deprecated in the 2.0 driver, so you should now use either updateOne() or updateMany().

Related

loopback destroyAll for couch db not working with query

I am trying out loopback-connector-couch database operator for deleting multiple records from CouchDB in one shot.
I have records _id in an array
Following the API spec for Loopback model as provided in the below api doc
https://apidocs.strongloop.com/loopback/#persistedmodel-destroyall
persist_model.destroyAll({id:{or:["49c199312b7dce75d69124f9e377a682","49c199312b7dce75d69124f9e377a682"]}},function(err,res){
console.log('records deleted success:'+res);
});
When executing the above code, it does not throw any error but its not deleting any documents
Would appreciate any help on this :)
The correct way is to use inq operator if you want to compare the value with multiple value stored in an array as follows:
persist_model.destroyAll({ id: { inq: [ "49c199312b7dce75d69124f9e377a682", "49c199312b7dce75d69124f9e377a682" ]}},
function(err, res) {
if (err) {
throw err;
}
console.log('records deleted success:' + res);
}
);
You can read more about inq operator here.

"not contains" query in SailsJS Waterline

How can I create the not contains query that returns true if the item does not contain a certain value. I'm running mongoDB if it is relevant.
I can use the contains successfully however receive an error when I introduce the not. I've tried it with find and where but get the same regex error both times. I can add the exact error if its relevant.
Working version:
model.find({attribute: {'contains': value}})
.exec(function(err, users) {
// happy code
});
The following complains about some regex error:
model.find({attribute: {not: {'contains': value}}})
.exec(function(err, users) {
// sad code
});
There was an issue raised and closed in 2013 about this. Maybe something changed recently?
https://github.com/balderdashy/waterline/issues/22
Alexei, I don't think this is supported by waterline currently. There is a related issue which is marked as feature and that you can track:
https://github.com/balderdashy/waterline/issues/666
So far, you can only use native feature of Mongodb I think.
Model.native(function(err, collection) {
collection.find({
"attribute" : {
$ne : value, //Not Equal
//OR
$nin : [value1, value2]// Not In
}
}).toArray(function(err, docs) {
if (err) return callback(err, docs);
res.json(null, docs);
});
});

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)

mongodb, get the result line after update

I'm working with mongodb, node.js and socket.io and I'm trying to reduce the number off access to the database. I need to update a line ; and after to return the updated line this is how I do :
db.collection('users').update({_id:targetID}, {$set: { 'property': 'value' }}, {safe:true}, function(err, result) {
db.collection('users').find({_id:targetID}).toArray(function(error, results){
//a socket.io resend the content
});
});
It works, but I really fell like I'm having a useless step here. The callback of the update function seems to be a boolean.
BTW, is there a better documentation than this one : http://docs.mongodb.org/manual/applications/update/ ? I'd like to find a list of properties and methods. The {safe:true} for instance. It seems not working without it but I can't find it in the reference.
Maybe I'm completely wrong and this is not the way I should do it. If you have a better idea... :)
You can use findAndModify to do this efficiently:
db.collection('users').findAndModify(
{_id: targetID}, [],
{$set: { 'property': 'value' }},
{new: true}, // Return the updated doc rather than the original
function(err, result) {
// result contains the updated document
}
);

MongoDB Query returning false results

I have streamlined this question for simplicity. Value is passed to the function, and if there is no document with {field1: value}, create that document; otherwise, call another function. However, this query will always find a document, or perhaps fires whatever_function() regardless. Why can I not get (!doc) to be true? This database is operative and queries/updates appropriately except for this issue.
db.doc.find({field1: value}, function(err, doc) {
if (!doc) {
db.doc.save({field1: value});
}
else {
whatever_function();
}
});
Find returns a cursor to the selected documents. Then, you should check that doc length is 0.

Resources