SAVE operation returning storage _id? - mongodb

Is there a save operation in mongoose.js or mongodb api, which returns the _id of stored entry?
In mongoose the following will save the Entry.
p.save(function (err) {
if (err) return handleError(err);
else console.log('saved');
})
})
Likewise db.collection.save(document) will save document in mongodb api. But in both cases, you need to query db again for _id, which I want to avoid. As it seems ineffient.

When you instantiate an object in Mongoose, the object will have an _id already assigned (as it's assigned on the client by default).
So, if you just check:
console.log(p.id);
You'll see that it has a value before you call save.
And in the case of using the native driver for Node.JS, the document is returned in the result parameter with the _id set.
var collection = db.collection("tests");
collection.insert(p, function(err, results) {
if (err) { return; }
// results in an array, and in this case
// results[0]._id would be available
});

Related

Fetch document by _id in express and mongodb

I am trying to create a todo list, where i am using mlab as my db provider.
tasks = db.connect().collection('tasks');
tasks.find().toArray(function (err, result) {
console.log("result", result) // giving me result
if(err) throw err;
res.render('tasks/index', {title:"Tasks",tasks:result});
})
Attached is one single shot of all routes output in console.
In the image (1) is the output of find().toArray()
(2) is get update and i am getting the id of task in the url route params.
(3) is after i run this findOne statment.
update function -> get task based on id
tasks.findOne({"_id":"59c91fbb4b262004f059f67f"}, function(err, task){
console.log(err)
console.log(task)
res.render('tasks/update', {title:"Update"});
});
I am getting null as value.(Note: I am hard coding the value for confirmation).
Let me know why i am getting null as the id matches (which you can refer from 1).
Task-2
Also, if i want to update, how shuld i send the altered values.
Regarding your first question, when matching on _id with Mongo you need to define your search criteria as an ObjectId :
tasks.findOne({"_id":ObjectId("59c91fbb4b262004f059f67f")}, function(err, task){
console.log(err)
console.log(task)
res.render('tasks/update', {title:"Update"});
});
Regarding the update, are you having some kind of trouble in particular ? The documentation has plenty of information regarding the structure of the query you're supposed to send :)

Mongoose/MongoDB: Can I update a document if I have a reference to it already without a query?

I perform db.collection.findOne( {query}... In the callback, if I successfully find an object, I want to modify one of it's properties...
,function(err, obj){
//is there a better way to do this since I already have a reference to the object? Searching the docs always gives me db.collection APIs
db.collection.update( {_id: obj._id }, { modifications}, function(err, obj){ ... }
}
Your subject includes mongoose so I guess you are using mongoose.
So there are two good ways you can do that (of course there are much more ways to do that):
Use findOneAndUpdate
model.findOneAndUpdate(query, {modifications}, function(err, obj) { //callback } )
read more about it here
your returned obj in the callback is a mongoose model, so you can modify it and save it:
function(err, obj){
obj.some_field = 'blabla';
obj.save();
}
Sure you can.
You can also use the findOneAndUpdate to use a single query. If nothing is found, nothing should be modified.

How can I get the _id from a single document using mongoose?

I want to query for a document with a given condition and have it return the _id for that document. Here is what I tried, but it doesn't work:
User.find(
{phone: phone},
null,
{},
function (err, data) {
user_id = data._id;
}
);
Basically, I'm trying to query the Users collection for a user/document with a certain phone number, and then have it return the _id for that user. What am I doing wrong?
If you're trying to find only one document you need to use findOne:
User.findOne({phone : phone}, function(err, data) {
if (err) return console.error(err);
user_id = data._id;
});
If multiple documents satisfy the query, this method returns the first document according to the natural order which reflects the order of documents on the disk.
If you want to get multiple documents you need to use find and your data parameter will then contain all users that matches your criteria.

Getting Mongoose Schema's and Documents without knowing Schema / Collection names?

Short Version: I basically want to do what show collections does in the mongo shell, in mongoose.
Long Version:
I want to create an application that allows users to basically create their own Schema's > Collections > Documents using mongo + mongoose + node.js.
The first step of this application would be to show previously created Collections and their Documents. But since these would be created by a user their names are not known.
The code I've found that came closest was:
function find (collec, query, callback) {
mongoose.connection.db.collection(collec, function (err, collection) {
collection.find(query).toArray(callback);
});
}
But I don't know what the name of the collection is so I can't pass the 'collec' parameter.
So, anyone know how to get the list of collections without knowing their names?
I ended up using node-mongodb-native (the mongo driver that mongoose works on top of) to get the collection names:
var nmn_connect = require('mongoose/node_modules/mongodb').connect;
nmn_connect('mongo://localhost:27017/DATABASE', function(err, db) {
if(!err){
db.collectionNames(function(err, names){ // what I was looking for
if(!err){
console.log(names);
db.close();
}else{
console.log(err);
db.close();
}
});
}else{
console.log(err)
}
});
The Object returned by mongoose.connect() has no method similar to collectionNames() that I can find.
I know nothing of mongoose, but this page suggests that you could use mongoose.connection.collections to access all collections: http://mongoosejs.com/docs/api.html
each collection again should have a name attribute.
try this:
mongoose.connection.db.collectionNames(function (err, names) {
});

Identify last document from MongoDB find() result set

I'm trying to 'stream' data from a node.js/MongoDB instance to the client using websockets. It is all working well.
But how to I identify the last document in the result? I'm using node-mongodb-native to connect to MongoDB from node.js.
A simplified example:
collection.find({}, {}, function(err, cursor) {
if (err) sys.puts(err.message);
cursor.each(function(err, doc) {
client.send(doc);
});
});
Since mongodb objectId contatins creation date you can sort by id, descending and then use limit(1):
db.collection.find().sort( { _id : -1 } ).limit(1);
Note: i am not familiar with node.js at all, above command is mongo shell command and i suppose you can easy rewrite it to node.js.
Say I have companies collection. Below snippet gives me last document in the collection.
db.companies.find({},{"_id":1}).skip(db.companies.find().count()-1);
Code cannot rely on _id as it may not be on a specific pattern always if it's a user defined value.
Use sort and limit, if you want to use cursor :
var last = null;
var findCursor = collection.find({}).cursor();
findCursor.on("data", function(data) {
last = data;
...
});
findCursor.on("end", function(data) {
// last result in last
....
});