Reputation: 7464
Basically, I'm trying to count the documents in a collection, and set the new document to that as the _id. I've tried a number of combinations, but none of them seem to work.
Here's what I tried:
var count = PostModel.find( function( err, posts ) {
if ( !err ) {
return posts.length;
}
else {
return console.log( err );
}
});
var post = new PostModel({
_id: count,
title: request.body.title,
content: request.body.content,
tags: request.body.tags
});
Returns:
{ message: 'Cast to number failed for value "[object Object]" at path "_id"',
name: 'CastError',
type: 'number',
value:
{ options: { populate: {} },
safe: undefined,
_conditions: {},
_updateArg: {},
_fields: undefined,
op: 'find',
model:
{ [Function: model]
modelName: 'Post',
model: [Function: model],
options: undefined,
db: [Object],
schema: [Object],
collection: [Object],
base: [Object] } },
path: '_id' }
And this:
var post = new PostModel({
_id: PostModel.find( function( err, posts ) {
if ( !err ) {
return posts.length;
}
else {
return console.log( err );
}
}),
title: request.body.title,
content: request.body.content,
tags: request.body.tags
});
Which returns the same error. However, when I add the following separately, it logs the length of the collection:
PostModel.find( function( err, posts ) {
if ( !err ) {
return console.log(posts.length);
}
else {
return console.log( err );
}
});
I tried using count()
in various ways as well, but I wasn't able to make any headway. Any insight on how to query the collection for the count, and set that as the _id would be great helpful.
Upvotes: 2
Views: 1496
Reputation: 3551
First of all, this is not recommended in MongoBD because it does not scale well.
But if you really want to do it, there are instructions here in the official MongoDB docs for a nice and safe way to do it.
Basically you use a small document to hold the current sequence ID, and each time you insert a document you both read and increment that sequence atomically. It is a lot more efficient than counting the documents each and every time you insert.
With your solution, what happens if two processes are running at the same time? You will potentially end up with identical IDs because your insert and sequence generation/count are not atomic.
Edit:
To get the count from your model use the following:
PostModel.count( function (err, count) {
if (err) ..
console.log('there are %d posts', count);
});
Edit by OP:
Per the comments below, the issue was with using the asynchronous functions synchronously. When all of the code was moved to the callback functions, it worked. Here's the solution:
PostModel.count( function (err, count) {
if (err)
console.log(err);
else {
console.log('there are %d posts', count);
var post = new PostModel({
_id: count,
title: request.body.title,
content: request.body.content,
tags: request.body.tags
});
post.save( function( err ) {
if( !err ) {
return console.log( 'Post saved');
} else {
console.log( err );
}
});
return response.send(post);
}
});
Upvotes: 2