Retrieving _id from mongoose create - node.js

Been searching for an answer to, what I think, is a common question.
I'm using Mongoose and Step.js (for code control).
I'm iterating through a couple records, creating individual models and hoping to return the created IDs. This is for a RESTful service I'm implementing to bulk insert records. I didn't include all the parts that Step is doing.
Code looks roughly like this:
var group = this.group();
for (var i in records) {
model.create(records[i], group());
}
The group function is Step, waiting for all the records to save.
The problem is once each record is saved, I'm hoping that Mongoose will return the _id associated with each create. It's only returning a result of the record itself without the proper _id value.
I've attempted creating the ObjectId and saving the model, but that failed and isn't recommended by a lot of people in a number of forums.
Thanks.

Related

bookshelf.js – how to fetch all records with empty query or no query at all?

Is it possible to fetch all records of a table in bookshelf without a query?
I'v got a Model named Person, and I'd like to retrieve all of its records.
What I am doing currently is this:
Person.where('id', '>', 0) ).fetchAll()
.then((result) => {
// doing stuff
});
which just doesn't feel right.
I was hoping for something like
// using empty querybuilder
Person.query().fetchAll()
or
Person.all //
Am I missing something?
I suppose model.fetchAll is the thing you are looking for.
Simple helper function for retrieving all instances of the given model.
See the API Reference of Bookshelf.js
In this case, you can use Model.fetchAll(), which fetches a collection of models from the database, using any query parameters currently set on the model to form a select query.

Adding extra value at Model.create with Mongoose

I have a large array that comes in from an API that I'd like to store straight into MongoDB.
Model.create(largeArray) ... // many documents created
The problem is, I have one additional key:value pair that I need to set for all documents in that array. It's a user id, and many documents are created for a given user once per API call. So for a given Model.create call, the user id is the same for every doc in the array.
Without mapping over the array, is there an efficient way of adding a field with a consistent value? Something like Model.create(myLargeArray, {userId: someUserId}) would be ideal, but I know this isn't the case with the Mongoose API.
function addDocsForUser(largeArray, someUserId) {
// each element of largeArray needs to have `userId: someUserId` added to it
return Model.create(largeArray)
}

Generate a unique ObjectId for a collection

I would like to generate a unique ObjectId for a resource to give back clients with the nodejs mongodb driver.
IE:
var ObjectID = require('mongodb').ObjectID;
var objectId = new ObjectID();
Reading about an ObjectId it seems that there are some cases in which this id may not be unique. Even though this is extremely rare I still cannot take a chance on having a duplicate id.
Question #1, Using this driver is it possible (even though unlikely) to get a duplicate id doing this:
var objectId = new ObjectID();
Question #2 (if above is not 100% guarantee to give a unique id):
Does this driver guarantee that for a certain collection the ObjectId that is automatically created when a new document is inserted is unique? If yes, how? If yes, can I somehow duplicate that behavior when calling new ObjectID() myself without a collection?
If the driver or the mongo server ensures (100% of the time) that for a collection every new doc gets a unique id, I could always have a collection of just ids, then when generating a new, empty doc for that collection I would ensure I get a unique ObjectId. However seems like overkill to have another collection just to store ids.
That being said some might ask why not just generate the ObjectId in a collection and update that doc later with data. The answer is that in my case data may not ever come later and I don't want to implement logic to check for empty docs that only contain an id.
It's very unlikely that the same ObjectID will generate as mongo guarantees unique ID. objectID is created with a combination of two same values and two different values (unix epoch time, and a random value). However, in any case of a duplicate, you won't be allowed to insert a document as objectID acts as a primary key and insert function will return duplicate key error to your callback. Read more here. The same error is returned if mongo node native library creates a duplicate ObjectID.
UPDATE: again after reading the code base, if "hypothetically" the objectID that was generated by the library isn't unique, the answer is no. We are not ensured by the library that the id is unique, but we are ensured of a duplicate error doesn't matter who or what sent the id.
Here's the process:
1. generates ID
2. Sends straight to server.
3. Returns results.
Mongo isn't looping in nodeJS with existing ids because the library isn't storing it in cache. Read the code base for the library.

Mongoose bulk insert or update documents

I am working on a node.js app, and I've been searching for a way around using the Model.save() function because I will want to save many documents at the same time, so it would be a waste of network and processing doing it one by one.
I found a way to bulk insert. However, my model has two properties that makes them unique, an ID and a HASH (I am getting this info from an API, so I believe I need these two informations to make a document unique), so, I wanted that if I get an already existing object it would be updated instead of inserted into the schema.
Is there any way to do that? I was reading something about making concurrent calls to save the objects, using Q, however I still think this would generate an unwanted load on the Mongo server, wouldn't it? Does Mongo or Mongoose have a method to bulk insert or update like it does with insert?
Thanks in advance
I think you are looking for the Bulk.find(<query>).upsert().update(<update>) function.
You can use it this way:
bulk = db.yourCollection.initializeUnorderedBulkOp();
for (<your for statement>) {
bulk.find({ID: <your id>, HASH: <your hash>}).upsert().update({<your update fields>});
}
bulk.execute(<your callback>)
For each document, it will look for a document matching the {ID: <your id>, HASH: {your hash}} criteria. Then:
If it finds one, it will update that document using {<your update fields>}
Otherwise, it will create a new document
As you need, it will not make a connection to the mongo server on each iteration of the for loop. Instead a single call will be made on the bulk.execute() line.

what's the best way to bind a mongodb doc to a node.js html page

In past with my PHP / Rails - MYSQL apps I've used the unique ID of a table record to keep track of a record in an html file.
So I'd keep track of how to delete a record shown like this (15 being the ID of the record):
Delete this record
So now I'm using MongoDB. I've tried the same method but the objectID ._id attribute seems to be a loooong byte string that I can't use conveniently.
What's the most sensible way of binding a link in the view to a record (for deletion, or other purposes or whatever)?
If the answer is to create a new id that's unique for each document in the collection, then what's the best way to generate those unique id's?
Thank you.
You could use a counter instead of the ObjectID
But this could create a problem when inserting a new document after you deleted a previous one.
See this blog post for more detail info on Sequential unique identifiers with Node.js and MongoDB.
Or you could use the timestamp part of the ObjectID:
objectId.getTimestamp().toString()
See the node objectid docs

Resources