Find all documents which have certain element is not undefined with Mongoose - node.js

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) {
...
});

Related

MongoDB updating child document does not affect the original document and vise versa

I'm using mongoose and have these schema:
var mongoose = require('mongoose');
mongoose.connect(/*...*/)
const usersSchema = new Schema({
email: String,
name: String
})
const ordersSchema = new Schema({
user: usersSchema, // <--- ref to usersSchema
createdOn: Date,
// ...
})
const UsersModel = mongoose.model('Users', usersSchema );
const OrdersModel = mongoose.model('Orders', ordersSchema );
The problem is when I insert an entity into Users collection and put that entity reference into the Orders.user field, It seems that Mongo does clone that object in the Orders collection.
// insert user:
var savedUser = await(new UsersModel({
_id: mongoose.Types.ObjectId(),
email: 'AAA#example.com'
})).save();
// insert order with user reference:
var savedOrder = await(new OrdersModel({
_id: mongoose.Types.ObjectId(),
createdOn: new Date(),
user: savedUser // <--- ref to users
})).save();
Now I modify the user document:
// update original user:
var userDocToModify = await UsersModel.findById(savedUser._id);
userDocToModify.email = "BBB#example.com";
await userDocToModify.save();
Assertion will fail in the below line:
var orderDoc = await OrdersModel.findById(savedOrder._id);
assert(orderDoc.user.email == userDocToModify.email, 'email not changed in the orderDoc.user.email!');
Actually what you are doing here, is not referencing userSchema. You are embedding that schema into orders schema. If you want to reference user you should do as below:
const ordersSchema = new Schema({
user: {type: mongoose.Schema.Types.ObjectId, ref: 'Users'}
createdOn: Date,
// ...
})
In this case you just store the user id in parent document.
Now if you want to get orders and the user within it, you can either use mongoose population or $lookup in mongoose aggregation.

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')

Importing a custom mongoose schema in another schema

My software has a mongoose Schema, let's call it carSchema, and I am exporting a model of the carSchema called Car. Example:
/* Car.js */
var carSchema= new Schema({
_id: Schema.Types.ObjectId,
type: String,
wheels: Number
});
carSchema.statics.drive = async function(){
...
}
module.exports = mongoose.model('Car', carSchema);
Now say my software has another schema called lotSchema in another file, that uses carSchema in it:
/* Lot.js */
var lotSchema = new Schema({
_id: Schema.Types.ObjectId,
carArr: [carSchema]
});
lotSchema.statics.getAllId = async function(){
return carSchema[0]['_id']
}
How can I properly import or export carSchema for use in lotSchema? Would a simple const carSchema = require('Car.js') suffice?
If you are not using not using es6/7 then you can do this
/* Car.js */
const carSchema= new Schema({
_id: Schema.Types.ObjectId,
type: String,
wheels: Number
});
carSchema.statics.drive = async function(){
...
}
module.exports.carSchema = carSchema;
module.exports.carModel = mongoose.model('Car', carSchema);
/* Lot.js */
const { carSchema , carModel } = require('./Car.js');
var lotSchema = new Schema({
_id: Schema.Types.ObjectId,
carArr: [carSchema]
});
lotSchema.statics.getAllId = async function(){
return carSchema[0]['_id']
}
You could do this in Car.js
module.exports = {
useCarSchema: function(myCollection) {
return mongoose.model('Car', carSchema, myCollection);
}
}
And this in Lot.js
var carSchema = require('./Car.js');
var Car = carSchema.useCarSchema(myCollection);
You can use Populate:
Population is the process of automatically replacing the specified
paths in the document with document(s) from other collection(s). We
may populate a single document, multiple documents, plain object,
multiple plain objects, or all objects returned from a query.
Example:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const carSchema= new Schema({
_id: Schema.Types.ObjectId,
type: String,
wheels: Number
});
const lotSchema = new Schema({
_id: Schema.Types.ObjectId,
cars: [{ type: Schema.Types.ObjectId, ref: 'Car' }]
});
mongoose.model('Car', carSchema);
mongoose.model('Lot', lotSchema);
Now, to populate works, you first need to create a car object car = new Car({}) and a lot object lot = new Lot({}), and then:
lot.cars.push(car);
lot.save(callback);

Aggregation and populate using mongoose

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);});

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!

Resources