Using 'generic' virtual for mongoose schema - node.js

I want to convert _id variable as id.
So i want to add virtual 'id' field to all the schema i am going to create, that will return the value of '_id' whenever i access 'id' field of the model.
from the documentation http://mongoosejs.com/docs/2.7.x/docs/virtuals.html
i found that, first i have to create schema then apply the virtual 'id' field individually.
I want to simply add virtual field to the base mongoose.Schema and then whenever i will create a new schema, that all will have virtual field without any manual effort on each of the individual schema.
EDIT :
i am also using Backbone.Model and i have created an 'id' field for each model. If i get the simply use id in the front end codes, i get the error that id field not exists. BUT when i set idAttribute as '_id' to each model then everything goes OK. That means backbone model want to have _id, and the reason behind mongoose schema have _id not id. So can i interpret that, mongoose does not automatically add virtual id mapped to _id? Correct me if i am wrong.

For backbone, "id" is it's default idAttribute name, so just don't add any code there and everything will work as intended.
For mongoose, the answer boils down to "it's complicated", but the main points are:
By default mongoose will give each schema a virtual called "id" which will be the document's _id as a string
However, by default .toJSON doesn't include virtuals, so when you send a mongoose document to backbone in the browser, it gets just "_id" and not "id"
to quickly get a JSON representation including the virtuals, use myModelInstance.toJSON({virtuals: true}). You'll get both "_id" and "id"
You need to read up on the transform options for toObject and toJSON to get a full picture of what you can do and how, but the gist is (based on examples straight from the docs)
// specify the transform schema option
if (!schema.options.toJSON) schema.options.toJSON = {};
schema.options.toJSON.transform = function (doc, ret, options) {
// remove the _id of every document before returning the result
delete ret._id;
}
schema.options.toJSON.virtuals = true;

Related

Cast to ObjectId failed for value "some_id" at path "_id" for model "Category"

when I use findOne from mongoose version 5.9.12, I got some error like this :
error
https://i.stack.imgur.com/8kAcY.png
my code:
[code][2]
https://i.stack.imgur.com/v8Prd.png
my models:
models
From the mongoose documentation:
If you want to query by a document's _id, use findById() instead of
findOne().
The id is cast based on the Schema before sending the command.
So the recommended way to do this is:
Category.findById(categoryId)
If you really want to use findOne and specify _id inside the filter, you can convert the string using
Category.findOne( { _id: mongoose.Types.ObjectId(categoryId) })
to an ObjectId.
Edit: The actual problem is that your categoryId contains a trailing whitespace which causes this problem: "5f05445a9789663d08fb12d2 " - it should be "5f05445a9789663d08fb12d2".

Missing Mongoose Schema Property Still Being Returned

Given a schema that looks like this:
var schema = new mongoose.Schema({ name: 'string', size: 'string' });
And the database contains "name" for all objects in the collection. But then I change it and remove name
var schema = new mongoose.Schema({ size: 'string' });
And then I do a find on it:
schema.find({}).exec().then( (objs) => {
// objs[0].name still exists
I thought that if the schema didn't specify a property then it wouldn't exist on the found objects. Is this not the case? Is the only way to remove a property, to actually remove it from the object in mongo?
Quoting from the original maintainer, Aaron Heckmann:
[M]ongoose "plays nice" with existing data in the db, not deleting it unless you tell it to.
[D]eleting the property would work if mongoose was able to hook into that even but alas it cannot. [H]owever you can completely remove the property from your document by setting the values to undefined which will trigger an $unset.
Source: Google Groups
Basically Mongoose attempts to be non-destructive to existing data. If a property is no longer needed you could run an update on the database to unset the value which would remove the property from every document in the collection.

Mongoose keeps giving both _id and id with same value

I have some Mongoose schemas, whose certain fields need getter and setters.
For that, i've set the following:
MySchema.set('toObject',{getters:true});
MySchema.set('toJSON',{getters:true});
Whenever I send/read the result of MySchema.find(), it gives me both _id and id fields, which have same value.
I think thats a virtual field (correct me if i'm wrong here)
How do i stop this? I don't want to process through each and every object and remove the field.
Documented here:
Mongoose assigns each of your schemas an id virtual getter by default which returns the documents _id field cast to a string, or in the case of ObjectIds, its hexString. If you don't want an id getter added to your schema, you may disable it passing this option at schema construction time.
Just set the id field to false while creating the schema:
var schema = new Schema({ name: String }, { id: false });

Update by Id not finding document

I am attempting to perform a relatively simple update using Mongoose:
var location = locationService.getLocation(typedLat, typedLong, travelRadius);
DocumentModel.update({_id : passedInId }, { location : location }, function(err, resp){
next(err, resp);
});
In this case passedInId is the string:
"561ee6bbe4b0f25b4aead5c8"
And in the object (test data I created) the id is:
"_id": ObjectId("561ee6bbe4b0f25b4aead5c8")
When I run the above however, matched documents is 0. I assume this is because passedInId is being treated like a string, however when I type it to an ObjectId:
var queryId = ObjectId(passedInId)
The result is the same, the document doesn't match. What am I missing? This seems like it should be obvious....
Mongoose will correctly interpret a string as an ObjectId. One of the following must be the case:
That record is not in the collection. Run a query in the mongo shell to check.
Mongoose I'd looking in collection other than the one containing your test data. Remember, by default, mongo will lowercase the name under which you register your model and will add an a "s" to it.
Lastly, and your answer speaks to this, maybe your model it's just not being updated with any new information.
This behavior was because I had not yet updated the model in mongoose to include the location element. There is no error, it just doesn't match or do anything.

MongoDB: Can I use a created ObjectId before saving my document

Using mongoose on node.js:
Can I access the _id field on a model before it has been saved to the database and be sure that the ID will not change?
For example, I would like to do the following:
var model = new mongoose.model('MyModel');
someOtherObject.myModelId = String(model._id);
// Some more code...
model.save(...);
In Mongoose, _id values must always be assigned client-side as the docs indicate that:
Mongoose forces the db option forceServerObjectId false and cannot be overridden.
So the model._id value you get in the first line of your code will not be changed unless you do it in your own code before calling model.save.

Resources