Whats the proper way to use mongoose population? - node.js

I have two schemas setup:
var ClientSchema = new Schema({
name: String
});
module.exports = mongoose.model('Client', ClientSchema);
And
var PlaceSchema = new Schema({
client: {type: mongoose.Schema.Types.ObjectId, ref: 'Client'},
address: String
});
module.exports = mongoose.model('Place', PlaceSchema);
If i get a list of places, i can populate the client easily like this:
Place.find({}).populate('client')
However, if i want to get a list of all the clients and all of their places, how would i make a query for that? Should i just simply loop through all of the clients and finding the places for it with Place.find({client:client._id) before returning the response?

Well if you have a number of places they will have their own unique ids, and for every place a client is connected to, you can have an array of placeId, you can push a placeId to this array everytime a client is connected to this place.`
var ClientSchema = new Schema({
name: String,
_address: [{type: mongoose.Schema.Types.ObjectId, ref: 'Place'}]
});`

This data structure would only work in one way, PlaceSchema do refer to ClientSchema but ClientSchema do not have any reference to PlaceSchema, the solution would be to define your ClientSchema this way :
var ClientSchema = new Schema({
name: String,
_address: [{type: mongoose.Schema.Types.ObjectId, ref: 'Place'}]
});
It seems kinda dumb but it would be much easier for your case

Related

Error when using _id as a property type in a Mongoose Schema

I am learning MongoDB and mongoose at the moment. I have a Archive and a User schema in mongoose:
archive.js
var mongoose = require('mongoose');
var User = require('../users/user');
var notesSchema = new mongoose.Schema({
author: User.userId,
text: String,
files:[String]
});
var archiveSchema = new mongoose.Schema({
name: String,
priority: String,
deadline: Date,
status: String,
assigned_memnbers: [User.userId],
notes: [notesSchema],
});
archiveSchema.virtual('archiveId').get(function() {
return this._id;
});
module.exports = mongoose.model('Archive', archiveSchema);
user.js:
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
username: String,
mail: String,
bio: String,
password: String
});
userSchema.virtual('userId').get(function() {
return this._id;
});
module.exports = mongoose.model('User', userSchema);
When I run my server i get the error
TypeError: Invalid value for schema path `author`, got value "undefined"
The the problem comes from author: User.userId, but I don't know how to make a reference between the two tables.
For reference, here is what my complete db design more or less looks like:
Any input on how to solve this problem or improve the overall design is welcome. Thanks you.
I think what you're talking about is a reference to other collection:
author: { type: Schema.Types.ObjectId, ref: 'User' }
and
assigned_members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
should work fine.
Source: Mongoose population
I faced the same issue.I had imported a module, It was just not exporting from another module. so I have added:
exports.genreSchema = genreSchema;

Nodejs- combine two diffrent lists into one

I've got two models in mongoose:
const user = mongoose.Schema({
name: String,
...
});
and
const moderator = mongoose.Schema({
name: String,
...
});
When I access these collections with:
user.find()
I get in response list of users and moderators separetly.
What I want to achive is to join these two list together to get a list based on this model:
const myDataSchema = mongoose.Schema({
user: {type: Schema.Types.ObjectId, ref: 'user'},
moderator: {type: Schema.Types.ObjectId, ref: 'moderator'}
});
Where one of attributes (either user or moderator) will be set.
I solved my problem. Instead of using the mongoose schema I created my "own object". My code:
let list= [];
users.forEach( function (user)
{
list.push({user: user});
});
moderators.forEach( function (moderator)
{
list.push({moderator: moderator});
});
It's probaly not the most efficient way but it works.

mongoose-schema - are both children array + parent doc's ID necessary?

I'm using a couple of one-to-many models and was wondering what the advantage of having both an array of "children" ObjectID()s and a "parent" model's ObjectID() in the child is. For example:
// a client will have a new card every ten visits
var ClientSchema = new Schema({
first_name: String,
last_name: String,
email: String,
cards: [] // ObjectID()s, <--- is this necessary?
});
var CardSchema = new Schema({
client: ObjectID(), // <--- or is this enough?
visits: []
});
I think the client: ObjectID() should do the trick in most cases, specially with the Population options Mongoose offers.
It suffices to store the reference ObjectId in one of the documents.
As you can read in the documentation or in this answer, the reference field needs a type and a ref. The name of field is arbitrary. Once you have done this and registered your models, you can use the models to populate your queries.
var clientSchema = new Schema({
first_name: String,
last_name: String,
email: String
});
var cardSchema = new Schema({
client: {
type: Schema.Types.ObjectId,
ref: 'client'
}
});
// models
var Card = mongoose.model('Card', cardSchema);
var Client = mongoose.model('Client', clientSchema);
Yet, it could be helpful to store an array of ObjectId's. However, this also creates a huge window for mistakes. A mismatch of foreign key and primary key, in SQL dialect. You can always do a count query if you need to count. I would say, do either the above or do this:
var clientSchema = new Schema({
first_name: String,
last_name: String,
email: String,
cards: [
{
type: Schema.Types.ObjectId,
ref: 'card'
}
]
});
var cardSchema = new Schema({
card_name: String
});
// models
var Card = mongoose.model('Card', cardSchema);
var Client = mongoose.model('Client', clientSchema);

ReferenceError Articles is not defined

I have several schemas defined. Here's one that works fine:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var NewsSchema = new Schema({
name: String,
route: String,
remoteURL: String,
articles: [{title: String, link: String, Image: String, contentSnippet: String}],
retrieved: Date,
dormant: { type: Boolean, default: false}
});
module.exports = mongoose.model('News', NewsSchema);
Here's a second one that's nearly identical:
var mongoose = require('mongoose'),
Schema = mongoose.Schema
// NewsSchema = new Schema({ name: String });
var ArticlesSchema = new Schema({
title: String,
link: String,
pubDate: Date,
image: String,
contentSnippet: String,
sourceName: String
// sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
});
module.exports = mongoose.model('Articles', ArticlesSchema);
I've loaded both of the modules at the top of my program, along with a bunch of other stuff like this:
players = require('./app/models/players'),
articles = require('./app/models/articles'),
If I create an instance of the first one with something like:
var player = new Players();
But if I try to create an instance of the second one with:
var item = new Articles();
I receive the error in the subject. In tracing the code I can see that the modules are in scope, so I don't believe it's something stupid like redefining a variable or something like that.
There are several questions of this nature posted here and none of the accepted answers apply.
Any ideas?
Well, upon further analysis, the working "model" no longer worked. It turns out that I had altered the case in the require statements at the top based on suggestions from Visual Studio Code. All is well now.
instead of
sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
use
sourceId: [ {type: Schema.Types.ObjectId, ref: 'NewsSchema'}]
would solve your problem

Node.js and mongoose module.exports on a model vs Schema

I have been following many tutorials concerning the MEAN stack, and I have come to a question I've found hard to answer (note: I found a possible duplicate when searching, but don't believe it answers my question)
Take this code for example, which can be found here
// app/models/nerd.js
// grab the mongoose module
var mongoose = require('mongoose');
// define our nerd model
// module.exports allows us to pass this to other files when it is called
module.exports = mongoose.model('Nerd', {
name : {type : String, default: ''}
});
After finishing the tutorial, I rewrote the code to attempt to replicate the lessons like so ("menu item" for a restraunt):
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name: {type: String, required: true},
description: {type: String, require: true},
price: {type: String, required: true},
ingredients: [{
name: {type: String, default: ''},
amt: {type: String, enum: ['None', 'Reg', 'XTRA'], required: true}
}]
});
I will be using an interface to create new menu items. Should I leave the code as is, or use a Schema?
Well. I was reading through code to post as an example for a difference, and came to this.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BearSchema = new Schema({
name: String
});
module.exports = mongoose.model('Bear', BearSchema);
I then noticed that the schema was defined inline (I think?) instead of being declared. I would assume that this is because later, it will be much cleaner for me to add more schema declarations in this model, along with methods. If anyone can provide me with clarification, I'll give you the answer!

Resources