I have two schemas:
Clinic:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ProcedureSchema = mongoose.Schema({
name: {
type: String,
trim: true,
required: true
},
alias: {
type: String,
trim: true,
required: true
}
});
var ClinicSchema = mongoose.Schema({
name: {
type: String,
trim: true,
required: true
},
procedures: [ProcedureSchema]
});
module.exports = mongoose.model('Clinic', ClinicSchema);
and Record:
var mongoose = require('mongoose'),
Patient = require('./patient'),
User = require('./user'),
Clinic = require('./clinic'),
Schema = mongoose.Schema;
var RecordSchema = Schema({
doctor: {
type: Schema.Types.ObjectId,
ref: 'User'
},
clinic: {
type: Schema.Types.ObjectId
},
date: {
type: Date
},
patient: {
type: Schema.Types.ObjectId,
ref: 'Patient'
},
procedure: {
type: [Schema.Types.ObjectId],
ref: 'Clinic'
}
});
module.exports = mongoose.model('Record', RecordSchema);
In record schema i store all ids of procedure, which sub-scheme for Clinic
I want to get full object of procedures in record.
I try this query:
Record.find({}).
populate('procedures.procedure').
populate('doctor').
populate('patient').
exec(function(err, records) {
...
});
But get only array of ids, instead array of objects.
Where is problem?
You totally mix all schemes:
populate('procedures.procedure')
But you have not procedures in RecordSchema. Even if it is type mistake, an you mean procedure.procedures - you don't have procedures in ProcedureSchema.
read more about references in MongoDB especially http://docs.mongodb.org/manual/applications/data-models-tree-structures/
Try to make nesting path less than 2. Something like this:
var User,
Procedure,
Clinic,
Patient,
Record;
function defineModels(mongoose, fn) {
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
User = new Schema({
...
});
Procedure = new Schema({
name: { type: String, trim: true, required: true },
alias: { type: String, trim: true, required: true }
});
Clinic = new Schema({
name: { type: String, trim: true, required: true },
procedures: [ProcedureSchema]
});
Patient = new Schema({
...
});
Record = new Schema({
'date': {type: Date, default: Date.now},
'doctor': {type: ObjectId, ref: 'User'},
'clinic': {type: ObjectId, ref: 'Clinic'},
'patient': {type: ObjectId, ref: 'Patient'},
'procedure': {type: ObjectId, ref: 'Procedure'},
});
mongoose.model('User', User);
mongoose.model('Procedure', Procedure);
mongoose.model('Clinic', Clinic);
mongoose.model('Patient', Patient);
mongoose.model('Record', Record);
fn();
}
exports.defineModels = defineModels;
Hope this help.
Related
i'm trying to design mongoose shema for users cleaner and customer, they have some common fields e.g. name, but also have extra (different fields) client(rating) and customer number. I'm not sure that my design is good.
I've created separate userSchema for customer and cleaner, and created separate address schema.
// User Schema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});
// AddressSchema
const AddressSchema = new mongoose.Schema({
city: {
type: String,
required: true
},
street: {
type: String,
required: true
}
});
// CustomerSchema
const CustomerSchema= new mongoose.Schema({
name: UserSchema,
address: AddressSchema
});
// CleanerSchema
const CleanerSchema= new mongoose.Schema({
name: UserSchema,
rating: {
type: Number,
required: true
}
});
My schema doesn't work. Could you give best practice example for my schema?
This is how I would define your Customer and Cleaner schemas. I don't think it's necessary to create the separate name and address schemas.
const CustomerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
address: {
city: {
type: String,
required: true
},
street: {
type: String,
required: true
}
}
});
const CleanerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
rating: {
type: Number,
required: true
}
});
I am having trouble querying my model, and using the .populate method to grab referenced documents of my object. Here are my schemas:
var userSchema = new Schema({
firstname: { type: String, required: true, unique: false },
lastname: { type: String, required: true, unique: false },
...
children: [{type: mongoose.Schema.Types.ObjectId, ref: 'Child'}],
});
var childSchema = new Schema({
firstname: { type: String, required: true, unique: false },
lastname: { type: String, required: true, unique: false },
...
legal_guardian_id: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}],
});
And here is how i'm trying to run my query:
User.findOne({ _id: '5b9d30083e33585cc0b8c710' })
.populate('children').exec((err, doc) => {
if (err) { return console.error(err); }
res.send(doc);
})
This results in "children": []
When I just use the findOne method and return the user, I get "children":["5b9d3f23d1408c5f4e2624f3"].
What am I doing wrong?
I have the following schema in mongoose that I would like to have as a nested array in another schema:
var NestedSchema = new Schema({
name: { type: String, required: true }
});
Some other schema that needs and array of the nested schema.
var EventSchema = new Schema({
name: { type: String, required: true, unique: true },
fields: [NestedSchema]
});
Which works just fine. However now I want to run some validation against that array.
var validators = // some validators
var EventSchema = new Schema({
name: { type: String, required: true, unique: true },
fields: [{ type: 'NestedSchema', required: true, validate: validators }]
});
Of course type: 'NestedSchema' does not work, it was a shoot in the dark. Does mongoose allow you to have an array of object based on schema
Using:
MongoDB shell version: 3.2.12,
Mongoose : 4.4.7
I managed to have an array based on schema that way:
var NestedSchema = new Schema({
name: { type: String, required: true }
});
var EventSchema = new Schema({
name: { type: String, required: true, unique: true },
fields: [{ type: [NestedSchema], required: true }]
});
Did not try validation, but I believe it will work as required works well. :)
I want to have each file for each model - i.e. user and country.
Currently, I solved this the following way:
person.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date,
country: {
type: Schema.Types.ObjectId,
ref: 'Country'
}
});
userSchema.methods.toString = function() {
return `I am ${this.username} and I'm from ${this.country.name}`;
}
module.exports = mongoose.model('Person', userSchema);
country.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var countrySchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
created_at: Date,
updated_at: Date,
people: [{
type: Schema.Types.ObjectId,
ref: 'Person'
}]
});
var Country = mongoose.model('Country', countrySchema);
module.exports = Country;
So my question is as follows: how does the mongoose reference two tables? For example, in Person schema, I reference the country by providing ref: 'Country', but I never included the model in the Person.js file. Am I doing something wrong here?
UPDATE:
Taking the below answer into the consideration, I now have 3 files:
database.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/people');
mongoose.set('debug', true);
module.exports = mongoose;
person.js
/*jslint node: true */
'use strict';
var mongoose = require('./database'),
Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date,
country: {
type: Schema.Types.ObjectId,
ref: 'Country'
}
});
userSchema.methods.toString = function() {
return `I am ${this.username} and I'm from ${this.country.name}`;
}
mongoose.model('Person', userSchema);
country.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var countrySchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
created_at: Date,
updated_at: Date,
people: [{
type: Schema.Types.ObjectId,
ref: 'Person'
}]
});
mongoose.model('Country', countrySchema);
Now when I include all these 3 files into a test file, e.g.:
var mongoose = require('./database'),
User = mongoose.model('Person'),
Country = mongoose.model('Country');
I get the following error: MissingSchemaError: Schema hasn't been registered for model "Person". I get the same error for Country if I delete the User variable. It appears as if mongoose is trying to define the model, not retrieve it. What seems to be the problem?
UPDATE 2:
OK, when I include now these documents, I do the following:
require('./person');
require('./country');
var User = require('mongoose').model('Person'),
Country = require('mongoose').model('Country');
I wanted to save multiple locations in the below schema and run geolocation queries.
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Offer Schema
*/
var LocSchema = new Schema({
'type': {
type: String,
required: true,
enum: ['Point', 'LineString', 'Polygon'],
default: 'Point'
},
coordinates: [Number]
});
var LocationSchema = new Schema({
address:{type:String},
loc:[LocSchema]
});
var OfferSchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Offer name',
trim: true
},
description:
{
type:String,
default:'',
required:'Please fill offer description',
trim: true
},
shortDesc:
{
type:String,
default:'',
trim: true
},
image:
{
type:String,
default:'',
required:'Please upload image'
},
locations:[LocationSchema],
created: {
type: Date,
default: Date.now
},
startDate: {
type: Date,
default: Date.now
},
endDate: {
type: Date,
default: Date.now
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
category:
{
type: Schema.ObjectId,
ref :'Category'
}
});
OfferSchema.index({'locations.loc': '2dsphere'});
mongoose.model('Offer', OfferSchema);
When I run save on the object I get "something went wrong" error, however I am able to save the document if I delete the index.
Can someone tell me if I am doing something wrong.