Querying on a virtual property in mongoose - node.js

I have a virtual property in my mongoose schema, I would like to know if I can query my documents using this property.
var PersonSchema = new Schema({
number: {type: Number, required: true},
name: {type: Date, required: true}
});
PersonSchema.virtual('capitalCaseName').get(function () {
return this.name.toUpperCase();
});
...
Person.find({"capitalCaseName": "DANIEL"}).exec();
...

No, you can't. Mongoose virtual properties only exist in the Mongoose model representation of documents, not in MongoDB itself where the query is performed.
Any field you need to query against must be defined in the schema as a non-virtual field and persisted to the database.

Related

How to populate mongoose models with other key without using _id(objectId) in ref

I am using MySQL data earlier. Now I am migrated to MongoDB. I want mongoose to populate some data. whereas I want to use my own key to populate in place of _id(objectId) in ref.
something like below.
Space schema
SpaceShema = mongoose.Schema({
id: Number,
cid: {
type: mongoose.Schema.Types.ObjectId,
ref: Client
},
space: String
});
I want to use id in ClientShema to populate in place of ObjectId
Below is the client schema
ClientShema = mongoose.Schema({
id: Number,
client: String,
});

Unique Index created in the DB is not working with mongoose save() on node.js [duplicate]

I want to browse the raw data stored in Mongodb by Mongoose. Where does it go? I have a Schema called Profile with several profiles stored in it, but using the Mongodb shell db.Profiles.find() and db.Profile.find() doesn't return anything.
The Schema,
var Profile = new Schema({
username : {type: String, index: true, required: true}
, password : {type: String, required: true}
, name : {type: String, required: true}
});
The default collection name when using Mongoose is the lower-cased, pluralized model name.
So if you're creating your model for the ProfileSchema as:
var ProfileModel = mongoose.model('Profile', ProfileSchema);
the collection name is profiles; so you'll find its contents as db.profiles.find() in the shell.
Note that you can provide your own collection name as the third parameter to mongoose.model if you don't like the default behavior:
var ProfileModel = mongoose.model('Profile', ProfileSchema, 'MyProfiles');
would target a collection named MyProfiles.

Creating dynamic schema in Mongoose using { strict: true }

I have this 2 schemas in mongoose:
The Booking schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bookingSchema = new Schema({
bookingNO: { type: Number, unique: true},
plateNO: String,
startDate: String,
bookedTime: Number,
creator: {type: Schema.Types.ObjectId, ref: 'User'}
});
var Booking = mongoose.model('Booking', bookingSchema);
The User schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
username: String,
password: String,
balance: Number,
bookings: [{type: Schema.Types.ObjectId, ref: 'Booking'}]
});
var User = mongoose.model('User', userSchema);
The problem with this design is:
Some Bookings were NOT created by a user - in which case the 'creator' field in Booking would be empty. Likewise, some Users do NOT necessarily contain a Booking - they may later on.
I was thinking about deleting the creator and bookings fields from the 2 Schemas, and using the { strict: false } option in Mongoose. Would this be the best option ?
If this is the case, I would have to add the 'creator' property to the Booking model, and 'bookings' property to the User, which would then get saved to the DB.
MOST importantly, due to the fact that I've removed the references from the Schema, how do I go about creating the reference in the case of using { strict: false } ?
Thanks in advance.
Unless a field has require:true flag, it can be left empty.
If you have a field which isn't defined in the Mongoose schema but is present in a document in MongoDB, you'll have to use doc.get('field') instead of just doc.field. Similarly for saving doc.set('field', value) and strict:false will be required otherwise it won't persist.
IMO you should have your schema inclusive rather than exclusive. Mongoose is just a wrapper for your data in MongoDB which at its heart is already schemaless.
In your specific case, you can create a booking without specifying a 'creator', because its of type ObjectId Mongoose will simply create the document and will leave that field empty. The user.bookings is a different matter as it is an Array, in which case Mongoose will always default to an empty array, even if it was left undefined when creating the document. In this case, would it be that bad to just leave the empty array there? It still represents the data accurately, where the user simply has no bookings, but are still able to potentially have them. If you explicitly don't want bookings, then yes, you'll either have to deal with strict: false, or manually $unset/delete the field from the documents.

Mongoose error: nesting Schemas

I have a question about nesting Mongoose schema.
Here is a simple code snippet
var aSchema = new Schema({bar: String});
var bSchema = new Schema({a: aSchema, foo: String});
var cSchema = new Schema({as: [aSchema], foo:String});
This will throw TypeError on bSchema: TypeError: Undefined type at 's' Did you try nesting Schemas? You can only nest using refs or arrays., but works fine for cSchema.
Just want to ask why bSchema does not work. Cannot find explanation in Mongoose doc. Thanks.
MongoDB is not a relational database. This can cause confusion for some who are used to the RDBS model (I still get tripped up occasionally...but I'm really not a DB guy).
Oftentimes, you'll find it beneficial to reference other documents in your Mongo entities. Mongoose schemas provide a very simple and effective way to do this that feels very relational.
When defining a schema that will store a reference to a different type of document, you define the relevant property as an object with a type and a ref. Typically when defining schema properties, you can simply say: a: Number; however, Mongoose provides many different options for a schema property other than type:
a: {
type: Number,
required: true
}
Setting required: true will prevent us from saving a document where the a property is not present.
Once you understand how to define your schemas with object definitions, you can leverage Mongoose's population mechanic:
a: {
type: Mongoose.Schema.ObjectId,
ref: 'a'
}
This tells Mongoose to store the ObjectId (a Mongoose-specific identifier) of a specific a document as the a property of our schema. Still following me?
When setting this property on a Mongoose document, you can simply say: doc.a = myA. When you go to save doc, Mongoose will automagically make the conversion and only store the ID in your database.
When retrieving a document that references another schema, you'll need to populate. I won't go into that, but its pretty simple - check out the documentation.
I was facing this issue as I was completely new to the MongoDB. Later I found we need to use the relationship as below with the help of Mongoose.
Below is my country schema.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var CountrySchema = new Schema({
name: { type: String, required: true },
activeStatus: Boolean,
createdOn: Date,
updatedOn: Date
});
And I can use this schema in my State schema as follows.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var StateSchema = new Schema({
name: { type: String, required: true },
country: {type: ObjectId, ref: "Country"},
activeStatus: Boolean,
createdOn: Date,
updatedOn: Date
});
Here I am using pointing to my other schema with the help of ref.

What collection does Mongoose put things in?

I want to browse the raw data stored in Mongodb by Mongoose. Where does it go? I have a Schema called Profile with several profiles stored in it, but using the Mongodb shell db.Profiles.find() and db.Profile.find() doesn't return anything.
The Schema,
var Profile = new Schema({
username : {type: String, index: true, required: true}
, password : {type: String, required: true}
, name : {type: String, required: true}
});
The default collection name when using Mongoose is the lower-cased, pluralized model name.
So if you're creating your model for the ProfileSchema as:
var ProfileModel = mongoose.model('Profile', ProfileSchema);
the collection name is profiles; so you'll find its contents as db.profiles.find() in the shell.
Note that you can provide your own collection name as the third parameter to mongoose.model if you don't like the default behavior:
var ProfileModel = mongoose.model('Profile', ProfileSchema, 'MyProfiles');
would target a collection named MyProfiles.

Resources