I'm pretty new to Mongodb and have so far successfully used Find, Insert, Update methods. However, with Delete function I am not able to access WriteResult
Insert (Works)
productCollection.insert(newProduct, function (err, result) {
callBack(err, { message: result["insertedCount"] + ' product created successfully.' });
});
Find (Works)
productCollection.find({}).toArray(function (err, docs) {
callBack(err, { product: docs });
});
Delete (Has Issues)
productCollection.remove({ id: pId }, { justOne: 1 }, function (err, result) {
callBack(err, { message: result});
});
Here when I return {message: result} I get
{
"message": {
"ok": 1,
"n": 0
}
}
But I want to actually read "n" from Result to show no of documents deleted
Tried following
{ message: result["n"] }
{ message: result["nRemoved"] }
But in both cases it returns empty object {}.
According to the 2.0 version of Node.js MongoDB Driver API, remove() method is deprecated, you can use removeOne() method instead:
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove
In order to receive number of documents that were removed, you need to use safe mode to ensure removal of documents. To do this, specify write concern by passing {w: 1} to removeOne() function:
productCollection.removeOne({ _id: pId }, { w:1 }, function(err, r) {
// number of records removed: r.result.n
callBack(err, { message: r });
});
Hope this helps.
Thanks Yelizaveta for pointing out the deprecated method. However in my case, following worked
productCollection.removeOne({ id: pId }, { w: 1 }, function (err, r) {
callBack(err, { message: r.result["n"]});
});
I could not get r.result.n working instead r.result["n"] worked, which I don't understand.
Related
i have looked all around trying to find a solution for this but i cant seem to find it
i am trying to see if a certain row exist in my nedb database and if it doesnt exist insert something but if it does exist then just move along here is what i have tried
function newAgent(pcName){
socket.broadcast.emit('newAgent', pcName)
agentList.find({agentName: { $nin: pcName}}, function(err, docs) {
agentList.insert({agentName: pcName}, function (err) {});
});
}
now i might be doing something stupid but im new to nedb so i have no idea what to use
How about trying something like this
function newAgent(pcName){
socket.broadcast.emit('newAgent', pcName)
agentList.find({agentName: { $in: pcName}}, function(err, docs) {
if(null === docs){
agentList.insert({agentName: pcName}, function (err) {});
} else {
//since it exists you might want update
agentList.update({
pcName: pcName
}, {
$set: {
//call fields to be updated
}
}, {}, callback);
}
});
}
I have a MySQL table with a url column and I want to get a list of every url value in the table. Structure:
In PHP using Laravel I could have done something like this to get an array of every url column value:
$boards = Board::all()->lists('url');
However, I cannot figure out how to do this using Sails JS. I've noticed that find() without any argument gets every row in the database but I can't find anything in the documentation that would allow me to either get a list of the values for the url column or a way to iterate over the returned collection.
I've tried this:
var boards = Board.find().exec(function(error, _boards) {
if(error)
{
return response.negotiate(error);
}
return _boards;
});
However, I can't actually seem to iterate over the returned data.
Any thoughts?
EDIT:
Full HomepageController.js:
module.exports = {
index: function (request, response) {
var data = {
currentDate: (new Date()).toString(),
boards: Board.query('SELECT url FROM board', function (error, results) {
if (error) {
return response.negotiate(error);
}
return results;
})
};
return response.view('homepage', data);
}
};
EDIT: Working Code:
module.exports = {
index: function (request, response) {
Board.query('SELECT url FROM board', function(error, results) {
if(error)
{
return response.negotiate(error);
}
return response.view('homepage', { currentDate: (new Date()).toString(), boards: results });
});
}
};
You can use a raw .query() to select individual columns:
Board.query('SELECT url FROM board', function (err, results) { ... });
However, keep in mind that your data will still look like this:
[{url: 'row 1 value'}, {url: 'row 2 value'}, ...]
// Note model
attributes: {
// Relations
notebook: {
model: 'Notebook'
},
}
and
// Notebook
attributes: {
// Relations
owner: {
model: 'User'
},
notes: {
collection: 'Note',
via: 'notebook'
}
}
in the controller:
Notebook.findOne({owner: user.id}, function (err, notebook) {
if (err || !notebook) {
return res.serverError(err);
}
// --> until here it goes all fine, finding the Notebook
Note.find().where({notebook: notebook.id}, function (err, notes) {
if (err || !notes) {
return res.serverError(err);
}
return res.json({notebook: notebook, notes: notes});
})
})
It is clear that I am trying to get all Notes related to the Notebook. When debugging, I get until the Note.find() and then I don't even enter the callback, so I don't get any results for Note. The err is null, so I wouldn't know if something's wrong.
I am betting that I have set up my model relations wrongly, but it seems correct to me, as from what I have read in tutorials.
P.S. I do have the records in the database, and the ER relations there are setup correctly, because inserting Note records works without problems.
The models relations seems to be fine.
I think the error come from the fact that there is no callback param in the where method.
Try this instead:
Note
.find()
.where({ notebook: notebook.id })
.exec(function (err, notes) {
...
});
I'm using Sails.js version 0.10.x, and am just starting to try out it's associactions stuff.
In my scenario I have a User who has many Documents.
so in /api/models/User.js I have:
module.exports = {
// snipped out bcrypt stuff etc
attributes: {
email: {
type: 'string',
unique: true,
index: true,
required: true
},
documents: {
collection: 'document',
via: 'owner'
},
}
};
and in /api/models/Document.js I have:
module.exports = {
attributes: {
name: 'string',
owner: {
model: 'user'
}
}
};
In my DocumentController I have the following:
fileData = {
name: file.name,
owner: req.user
}
Document.create(fileData).exec(function(err, savedFile){
if (err) {
next(err);
} else {
results.push({
id: savedFile.id,
url: '/files/' + savedFile.name,
document: savedFile
});
next();
}
});
Looking in my local mongo database via the command line I can see that the documents have the owner field set as follows "owner" : ObjectId("xxxxxxxxxxxxxxxxxxxxxxxx") which is as expected.
However when I inspect the req.user object later in the DocumentController via sails.log.debug("user has documemts", req.user.documents); I see
debug: user has documents [ add: [Function: add], remove: [Function: remove] ]
And not an array of Document objects.
In my resulting slim template
if req.user.documents.length > 0
ul
for doc in req.user.documents
li= doc.toString()
else
p No Documents!
I always get "No Documents!"
I seem to be missing something obvious but I'm not sure what that is.
I worked this out by wading through the Waterline source code.
Firstly, as I hoped, both sides of the association are affected by the creation of the Document instance, and I simply needed to reload my user.
Within the controller this is as simple as User.findOne(req.user.id).populateAll().exec(...)
I also modified my passport service helper as follows
function findById(id, fn) {
User.findOne(id).populateAll().exec(function (err, user) {
if (err) return fn(null, null);
return fn(null, user);
});
}
function findByEmail(email, fn) {
User.findOne({email: email}).populateAll().exec(function (err, user) {
if (err) return fn(null, null);
return fn(null, user);
});
}
Now the user, and its associations, are loaded properly per request.
I had to dig through the source to find the populateAll() method as it's not actually documented anywhere I could find. I could also have used populate('documents') instead but I am about to add other associations to the User so need populateAll() to load all the relevant associations.
Waterline associations docs
Waterline /lib/waterline/query/deferred.js#populateAll
So I'm listening for an event with socket.io, once that fires I'm trying to update a record to a new value.
socket.on('contentEdited', function (newContent) {
collection.update(
{ '_id' : ObjectId("5279262e74d92da751eb2b8e") },
{ $set: {
'content': newContent
}
}
), function (err, result) {
if (err) throw err;
console.log(result)
};
});
The syntax works in the shell, but throws the following error in node when the event fires:
Error: Cannot use a writeConcern without a provided callback
I tried adding an function at the end afterwards for basic error checking, but I'm not sure how to provide a callback in the way mongo expects.
Still kinda new to this, thanks
I think your problem is that the callback function needs to be inside the update function call instead of outside it. The format for the nodejs MongoDB driver can be found here: http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#update
So it should look like this:
collection.update(
{ '_id' : ObjectId("5279262e74d92da751eb2b8e") },
{ $set: { 'content': newContent } },
function (err, result) {
if (err) throw err;
console.log(result);
})
Note that the parentheses has moved after the callback function.
You could also set the write concern to "unacknowledged" instead of "acknowledged."
The MongoDB concept of "Write Concerns" determines how certain you want to be that MongoDB successfully wrote to the DB. The lowest level of write concern, "Unacknowledged" just writes data to the server and doesn't wait to response. This used to be the default, but now the default is to wait for MongoDB to acknowledge the write.
You can learn more about write concerns here:
http://docs.mongodb.org/manual/core/write-concern/
To set the write concern to unacknowledged, add the option {w: 0}:
collection.update(
{ '_id' : ObjectId("5279262e74d92da751eb2b8e") },
{ $set: { 'content': newContent } },
{ w : 0 });
yes. maybe you have the wrong syntax. and this might make it even better
socket.on('contentEdited', function (newContent) {
collection.update(
{ '_id' : ObjectId("5279262e74d92da751eb2b8e") },
{ $set:
{ 'content': newContent }
},
{returnOriginal : false},
function (err, result) {
if (err) throw err;
console.log(result);
});
})