Aggregation and populate using mongoose - node.js

I have two collection like this:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var GradeSchema = new Schema({
gID: { type: Number, ref: 'User'},
grade: Number,
created_at: Date,
updated_at: Date,
type: Number
});
var Grade = mongoose.model('Grade', GradeSchema);
module.exports=Grade;
and:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var UserSchema = new Schema({
name: String,
lastName:String,
uID: { type: Number,ref:'Grade' },
phone: String
});
var User = mongoose.model('User', UserSchema);
module.exports=User;
how can i first aggregate and then populate to have both collection information??
i used this command using $lookup in mongodb and it return my suggested documents:
db.grades.aggregate([{$lookup
{from:"users",localField:"gID",foreignField:"uID",as: "result"}},{$match:
{"type":0}},{"$sort":{"grade":-1}}])
but when i used this in mongoose the "result" is [] and connection to user collection is failed:
Grade.aggregate([{"$lookup":
{"from":"User","localField":"gID","foreignField":"uID","as": "result"}},
{"$match":{"type":3}},{"$sort":{"grade":-1}}]).exec(function(err, data)
{console.log(data);});

Related

Mongoose Find By Ref ID

so I have two schemas, User und Company
const UserSchema = new mongoose.Schema({
_createdAt: Date,
company: {type: mongoose.Schema.Types.ObjectId, ref: 'company'},
email: String,
});
const CompanySchema = new mongoose.Schema({
_createdAt: {
type: Date,
required: true
},
name: {
type: String,
required: true
}
});
const userModel = mongoose.model("user", UserSchema, "user");
const companyModel = mongoose.model("company", CompanySchema, "company");
I would now like to query for a specific User by his Company _id, but for some reason this is not working, it returns an empty array even though I have a user with the exact company ObjectId in my Database.
userModel.find({company: "5cfa4352ffc1c8135d8276a4"})
.exec((err, user) => {
console.log(user);
}
In my mongo shell the command
db.user.find({company: "5cfa4352ffc1c8135d8276a4"})
returns the users as expected so why does this not work in mongoose? Thanks in advance
Try this
const ObjectId = require('mongodb').ObjectID;
then
db.user.find({company: ObjectId("5cfa4352ffc1c8135d8276a4")})
I hope it will work
If you want to find by that id you probably need to do this:
const mongojs = require('mongojs');
const ObjectId = mongojs.ObjectId;
db.user.find({company: ObjectId("5cfa4352ffc1c8135d8276a4")})
Since you are using moongose, you can get the ObjectId like this:
const mongoose = require('mongoose');
const objectId = mongoose.Types.ObjectId('569ed8269353e9f4c51617aa')

Mongoose : Error referencing sub schema

My user model
'use strict';
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var UserSchema = new mongoose.Schema({
id: String,
username: String,
firstName: String,
lastName: String,
initials: String,
password: String,
age: Number,
dateJoined: Date,
contactNo: String,
email: String,
about: String,
groupId: Number,
adminMode: Boolean,
simpulPoints: Number,
})
//Define model for user
const User = {
UserModel: mongoose.model("user", UserSchema),
}
module.exports = {
UserSchema : UserSchema,
User : User
}
My Events Model
'use strict';
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var UserSchema = require("../models/user").UserSchema
var EventSchema = new mongoose.Schema();
EventSchema.add({
id: String,
title: String,
description: String,
organizerId: String, //Simpul admin user responsible for event
startDate: Date, //MM-DD-YYYY HH:MM:SS:sssZ
endDate: Date,
group: String,
locaction: String,
googleMapsLink: String,
hasPassed: Boolean,
attendees: Number,
registeredUsers: [UserSchema],
groupId: Number,
adminMode: Boolean,
simpulAward: Number,
});
//Define model for evnt
var Event = {
EventModel : mongoose.model("event", EventSchema),
}
module.exports = {
Event : Event,
EventSchema : EventSchema
}
I'm getting the infamous "throw new TypeError('Invalid value for schema Array path" error with the 'registeredUsers' field. I've followed multiple posts with the same problem and can't seem to find where I am going wrong. According to my knowledge, I've exported the schemas appropriately. Any help/tips welcome
I ended up moving the Schema declarations out into a separate file and it seemed to do the trick. Suspect it must have been some file rights issue VSCode had with the users.js file

MissingSchemaError: Schema hasn't been registered for model when crossed references

I'm using mongoose and I'm trying to do this:
user.model.js
var mongoose = require('../../db/mongodb.connector'),
Schema = mongoose.Schema;
require('./offer.model');
var Offer = mongoose.model('Offer');
var userSchema = new Schema({
name: { type: String },
myOffers: [{type: Schema.Types.ObjectId,ref: 'Offer'}],
});
module.exports = mongoose.model('User', userSchema);
offer.model.js
var mongoose = require('../../db/mongodb.connector'),
Schema = mongoose.Schema;
require('./user.model');
var User = mongoose.model('User');
var commentSchema = new Schema({
user: {type: Schema.Types.ObjectId,ref: 'User'},
comment: {type: String},
likes: {type: Number}
});
var offerSchema = new Schema({
name: {type: String},
comments: [commentSchema],
likes: {type:Number}
});
module.exports = mongoose.model('Offer', offerSchema);
My problem is when I execute the server it returns :
D:\WebStorm\Alertame-Backend\node_modules\mongoose\lib\index.js:362
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "User".
Use mongoose.model(name, schema)
at Mongoose.model (D:\WebStorm\myproject\node_modules\mongoose\lib\index.js:362:13)
at Object.<anonymous> (D:\WebStorm\myproject\db\models\offer.model.js:9:21)
.......
If I remove the inports in offer.model the server start normally
require('./user.model');
var User = mongoose.model('User');
EDIT TO EXPLANATION:
Offers are a individual entity and it would be assigned or not to an existing user (user has an array of assigned offer refs). On the other hand offers have an array of comment refs wich be writed by existing users.
What would I'm doing wrong?
You are trying to include offer.model from user.model and user.model from offer.model. Each file tries to include itself.
That is the reason it gives an error of undefined schema!

Find all documents which have certain element is not undefined with Mongoose

This is a Event model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Event = new Schema({
eventname: String,
location: String,
note: String,
remind: String,
userid: mongoose.Schema.Types.ObjectId,
projectid: mongoose.Schema.Types.ObjectId,
});
module.exports = mongoose.model('Event', Event);
If event belongs to a project it will save the id of project in projectid, if not projectid will be undefined.
I wonder how to find all the documents which have projectid is not undefined with mongoose?
You can use Query#exists for that:
Event.where('projectid').exists().exec(function(err, docs) {
...
});

Mongoose Sub-documents on separate files, how to embed them

I'm defining my application models and i have separate files for each model that i'm defining, my question is, i need to create a model that use a sub-document, but that's on another file, how can i use that Schema on my model ? what i mean is that all examples i've seen declare the Child model and the Parent on the same file, example:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
children: [childSchema]
});
I have one file called user.js that defines the user model :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
_id : Schema.Types.ObjectId,
username : String,
});
module.exports = mongoose.model( 'User', userSchema );
And on another file called sport.js i have the other model definition for the sports:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var sportSchema = new Schema({
_id : Schema.Types.ObjectId,
name : String
});
module.exports = mongoose.model( 'Sport', sportSchema );
So on my user model I need to define a field for the sports that the user will follow, but i do not know how to define that sub-document since the sports definition is on another file, I tried this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SportsModel = require('sport');
var userSchema = new Schema({
_id : Schema.Types.ObjectId,
username : String,
sports : [SportsModel]
});
module.exports = mongoose.model( 'User', userSchema );
But i'm not sure if that's the correct way since what i'm exporting is the model, not the Schema.
Thanks in advance, i want to define each model on separate files to maintain order.
You can access a Model's schema via its schema property. So this should work:
var userSchema = new Schema({
_id : Schema.Types.ObjectId,
username : String,
sports : [SportsModel.schema]
});
Use ref
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
_id : Schema.Types.ObjectId,
username: String,
sports : [{ type: Schema.Types.ObjectId, ref: 'Sport' }]
});
module.exports = mongoose.model('User', userSchema);
Incidentally, with ref, you can use .populate('sports') when you query, and mongoose will expand those types for you.

Resources