Is this query possible in nosql (with mongodb)? - node.js

I use mongoose in my node.js app, and basically have the following models:
// Define Car model
CarSchema = new Schema({
brand : String,
type: String,
maxSpeed : Number
});
mongoose.model('Car', CarSchema);
// Define User model
UserSchema = new Schema({
lastname : String,
firstname : String,
cars : [CarSchema]
});
mongoose.model('User', UserSchema);
I'm really new to NoSQL and I really want to give it a try but I first need to study if this really fits my needs.
With the above models, will I be able to create a query listing all the Users who have a particular type of car among their personal cars ?

I don't how to do it in mongoose. But in mongodb it possible. So, in mongodb shell query will looks like this:
db.users.find({"cars.type":"sport"})
Above query return all users thats have car with type 'sport' in their nested collection of cars.
Mongodb dot notation documentation.

Related

mongoDB chat system database structure

i am trying to create group chat system using mongoDB but in mongoose object type is supported how can i create model like this(inserting image below)? and also query this data? i've tried to create schema but didnt work
sample of model (dummy)
const chatSchema = new mongoose.Schema({ users: Array, texts:[{ user: String, text: String, time: Date, }] });
Try this schema. Users who will be in group chat will added in users field. The text will have author(user), text(text) and date(time).

How to use find() called from mongoose model to get just that specific model from a collection that contains multiple models?

I have these specific schemas:
const PersonSchema = new Schema({
Name: String,
})
const StudentSchema = new Schema({
Class: String,
Professor: String
})
const ProfessorSchema = new Schema({
Class: String,
Students: Number
})
I produce the following models, note that the Student and Professor are extended from the Person model:
mongoose.model("Person", PersonSchema, "objects" )
Person.discriminator("Professor", ProfessorSchema, "objects")
Person.discriminator("Student", StudentSchema, "objects")
I store all of them in the same collection "objects" and when I call the find() method from any of the models I get all the objects in the collection and not just from the specific model. How can I just retrieve from the collection one specific model?
The way to solve this problem of getting all the documents from all models when asking just a specific one is to provide some specific arguments arguments when constructing the model.
Instead of just providing the collection name in the model:
Person.discriminator("Professor", ProfessorSchema, "objects")
You should provide a conjunct of arguments that specify the collection and the type attribute:
const baseOptions = {
collection: "objects",
discriminatorKey: '__type'
}
const Professor = Person.Model.discriminator("Professor", ProfessorSchema, baseOptions)
The default discriminatoryKey now has the value equal to the model name instead of its default value that is the collection name. When you use the find() method it only retrieves the type connected with the model.

Mongodb Collection name

I've created a database in MongoDB using mongoose. Although everything works fine, but when I check mongodb the name of the collection has extra 's' in its name. The collection name created is employees. What could be wrong, or is it just the naming convention of mongoose?
const mongoose = require('mongoose');
let employeeSchema = mongoose.Schema({
name: String,
email: String,
department: String,
doj: Date,
address: String
});
const Employee = mongoose.model("employee", employeeSchema);
module.exports = Employee;
It doesn't just add an extra 's' but it makes the correct plural of the name.
For Example : Mouse will be converted to mice
You can disable it by:
mongoose.pluralize(null);
Reference Link: https://github.com/Automattic/mongoose/issues/5947
So you have two options for controlling document names in mongoose.
If you just want to disable pluralization, you can do it with mongoose.pluralize(null) as in Ankit's answer.
And if you want to change your collection name whatever you want, you can do:
mongoose.model("employee", employeeSchema, { collection: 'myEmployee' } )

Data modeling in mongoDB - Social-media app

I'm trying to build some sort of a social media app using node.js and mongoDB.
I have a mongoose schema for 'User', and when i render some user page on the app, it needs to also show all of his posts/images/list of friends and etc...
right now i have a mongoose schema for 'UserPost' and also for 'Image', and when i save an image for example, it has a field which keeps the username of the user who uploaded it, so when i render the user page it finds all of his images.
It is the first time i'm dealing with db's so i heard that i might have to use a reference data instead of embedded data.
can someone explain to how should i organize the data model for my app?
It's very handful to use mongoose population for handling db references
Define your schemas like these:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var userSchema = Schema({
name : String,
posts : [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
var postSchema = Schema({
title : String,
images : [{ url: String, filename: String }]
});
var User = mongoose.model('User', userSchema);
var Post = mongoose.model('Post', postSchema);
According to mongoose population docs, you can get all your data:
User.findOne().populate('posts').exec(function(error, user) {
console.log(user.posts) // there are populated posts objects inside array
})
Not sure, is it a good idea to use separated collection for image uploads, it's simpier to embed it inside Post (or User), but you may always add { type: Schema.Types.ObjectId, ref: 'Image' } for images
MongoDB is a NoSql DBMS. It means, you schould not create references between data fields, because the performance coming from NoSql will be killed: https://en.wikipedia.org/wiki/NoSQL
But, if you are really thinking you need references, checkout this: http://docs.mongodb.org/master/reference/database-references/
You can reference to a data document in the mongoDB by the _id ("Page"=>"createdBy" = "User"=>"_id" for example).
It depends of what kind of data you want to embed. MongoDB has object size limits according to the storage engine you use. Thus you should predict or estimate the the size of the object you want to embed.
See more about limits here: http://docs.mongodb.org/master/reference/limits/
See more about references here: http://docs.mongodb.org/master/reference/database-references/

Render every subdocuments of all documents with mongoose

I have a user model and a pet model, using Mongoose.
user model :
var userSchema = mongoose.Schema({
email : String,
password : String,
pets : [Pet.schema]
});
module.exports = mongoose.model('User', userSchema);
pet model :
var petSchema = mongoose.Schema({
name : String
});
module.exports = mongoose.model('Pet', petSchema);
I'd like to render all the pets of all users in a page. I tried to do :
app.get('/pets', function(req, res) {
Pet.find({}, function(err, pets){
res.render('pets.ejs', {"pets":pets});
});
});
But I only get an empty array [ ].
How could I get every Pets ?
More generally, I will have to use Pet model independently from the User. Should I change the way my models are constructed ?
Thanks for your help !
It looks like you're trying to embed the Pet sub document and use as if it weren't embedded.
First, if you're doing embedded, you need to define the schema for Pet before you use it (create it first). If you're embedding, you can't do a find on the Model for pets that way.
Mongoose Subdocuments
If, instead, you want to store a reference to a Pet inside a User, you need to store its ObjectId.
pets : [{ type: Schema.Types.ObjectId, ref: "Pet"}]
You would then likely use populate to fill the pets property at run time.

Resources