Mongoose: Generate Schema from existing data - node.js

For example, I have user collection in db:
{'_id':0, 'name': 'Joe', 'score':[80, 33]}
{'_id':1, 'name': 'Moe', 'score':[90, 81]}
... ...
How can I read this data with existing format, which means, use it's existing schema without create a new one.
I read Mongoose doc and googled for a while but didn't find satisfied answer.

When using mongoose with an existing collection, you have to reference the collection in your mongoose schema. The way to do this is to add the name of the collection to your schema. So if your collection is in 'mongodb://localhost:27017/test' and called 'things', you would use:
~~~
const Schema = mongoose.Schema;
const ThingSchema = new Schema({
name: {
type: String
}
});
const Model = mongoose.model('Thing', ThingSchema, 'things');
module.exports = Model;
~~~
Thanks to http://chrisflx.blogspot.fr/2014/04/nodejs-mongoose-with-preexisting-data.html?m=1

It will work if you make a model with the same schema.
var schema = new mongoose.Schema({ name: 'string', score: [] });
var user = mongoose.model('User', schema);
Edit:
Mongoose is an ODM, so you need a schema to create objects. If you need to run queries and get raw data from the database, I would stick with this library:
https://github.com/mongodb/node-mongodb-native

Related

How to clone a Mongodb database with Mongoose

Is there a way to clone a collection or entire Mongodb database (my databases only have one collection so both options are OK) with Mongoose? I saw that there is a possibility to execute raw Mongo commands with Mongoose. What command can I use to clone an entire collection or db from one db to another?
Thanks in advance.
I had a hard time doing this I don't have any reference.
However, this is how I did on my end.
1, I created another collection within the same
db: mydb
collections: books, oldbooks
2, Since I only know how to connect to one database at a time, I stick to this:
mongoose.connect(process.env.CONN_STR);
3, On your existing collection, in this case, books, we have this code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var BookSchema = new Schema({
name: String
})
module.exports = mongoose.model('Book', BookSchema);
4, I created a different Schema for the backup so I can specific the name of the collection:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var BackupSchema = new Schema({
name: String
}, {
collection: 'oldbooks'
})
module.exports = mongoose.model('BackupBook', BackupBookSchema);
NOTICE: that we specified the collection in BackupBook Schema collection: 'oldbooks'. The idea is to replicate the existing schema to the backup schema.
5, Fetch and save each entry in the collection:
Book.find()
.exec((err, books) => {
if(err) throw err
else {
books.forEach( (book) => {
var backup = new BackupBook();
backup._id = book._id;
backup.name = book.name;
backup.save((err, backup) => {
})
})
}
})
TLDR: Create a different collection as backup. Query each entry of the collection then save to the backup Schema individually. Note, the backup schema must specify the name of the collection.

How to associate a mongoose model with the right MongoDB collection in Express.js app?

how to point to particular collection in mongodb using mongoose ORM in express js app .
NA
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var personSchema = new Schema({
name: String,
age: Number
});
module.exports = mongoose.model('person', personSchema);
consider my mongo database have multiple collection ,so how will my above code will point to particular collection.
I'm really sorry my selected answer is not accurate. I can't delete it because it is accepted. The accurate answer to your question is, mongoose.model('person', personSchema); will automatically create a plural lower case version of the model name.In this case, it will automatically create a collection persons in mongoDB if it doesn't exist already.
If you want to override this default behavior, you can do it like this:
var personSchema = new Schema({
name: String,
age: Number
},
{
collection:'people'
});
or
mongoose.model( 'person', personSchema, 'people' ) so you refer to it as person, but collection name will be people
Usually we follow convention of naming the collection plural in mongoDB. For example in MongoDB, we create users table, but use singular in Node.js. So the exports would be:
module.exports = mongoose.model('users',UserSchema)
And in other script, we require it as follows:
const User=require('<pathToModel>/user')
This means we are referring to the model as User, it is based on UserSchema and the collection associated with this is users
In your code, you could do this:
module.exports = mongoose.model('person', personSchema);
If you have a specific collection you want documents based on a specific model to go into, you can use mongoose.model('person', personSchema, collection).
Or, you could name the desired associated collection in the Schema definition:
var dataSchema = new Schema({..}, { collection: 'data' });
https://mongoosejs.com/docs/guide.html

document must have an _id before saving mongoose error

I am trying to create a schema.
I keep getting the document does not have an _id error, besides the code below I did try to initialize it explicitly, but nothing works.
var UserSchema = new mongoose.Schema({
_id: mongoose.Schema.ObjectId,
username: String,
password: String
});
var User = mongoose.model('user', UserSchema);
http://mongoosejs.com/docs/guide.html#_id reads:
Mongoose assigns each of your schemas an _id field by default if one is not passed into the Schema constructor.
If you explicitly define _id type in the schema, it's your responsibility to set it:
User._id = mongoose.Types.ObjectId('000000000000000000000001');
_id is the primary key for document in a mongoDB. You don't have to specify the _id in your Schema. It will be added automatically once the document is created.
Here is the sample code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = new Schema({
username: {
type: String
},
password: {
type: String
}
});
module.exports = mongoose.model('User', User);
I think you dont need to define the _id. Try without and see if it works.
Also if that is not the problem try this:
_id: { type: Mongoose.Schema.Types.ObjectId }
if you want to define _id in your schema explicity you should assign a value to "_id" for each insertation. you have two way to solve this problem :
1. remove "_id" from your schema and mongoose generate id automatically.
2. assign a value to _id :
var ObjectId = require('mongodb').ObjectID; // or var ObjectId = require('mongoose').Types.ObjectId; "but the first worked for me"
User._id = objectId('1111111111111111111');
simple remove the line from your code
_id: mongoose.Schema.ObjectId

Mongoose nested schema vs nested models

What is the difference between nesting schema in schema (subdocuments) vs creating two separate models and referring to them, What about their performance?
subdocuments:
const postSchema = new Schema({
title: String,
content: String
});
const userSchema = new Schema({
name: String,
posts: [postSchema]
});
module.export = mongoose.model('User', userSchema);
nested models (Populating by reference):
const postSchema = new Schema({
title: String,
content: String,
author: { type: String, ref: 'User' }
});
module.export = mongoose.model('Post', postSchema);
const userSchema = new Schema({
name: String,
posts: [{ type: Schema.Types.ObjectId, ref: 'Post'}]
});
module.export = mongoose.model('User', userSchema);
Edit: This is not a duplicate question.
In this question: Mongoose subdocuments vs nested schema - mongoose subdocuments and nested schema is exactly the same.
BUT nested models creating a separate collection in database.
My question is what is diffrence in nested schema vs nested models, not subdocuments vs nested schema.
When using subdocuments, you actually have a copy of the data within your parent-document, wich allows you to get all the document + sub-document-data in a single query.
When using "nested models" you're not really nesting them, but referencing from the parent-model to the child-model. In this case you have to use population, which means you can't get all the data in a single query.
In short: subdocuments actually nest the data, and your "nested models" only reference them via their id

What is an equivalent work around to $setOnInsert in mongoose

I have below collection structure in mongodb. Say
Collection - student - _id,firstname,lastname,class
Now I want to insert 2 extra columns say marks as array{mark1:m1,mark2:m2}when inserting a newrow`.
I did it as below but it inserted record excluding marks values.
var student=new Student({
_id:id,
firstname:result.fname,
lastname:result.lname,
class:result.class,
marks:{
mark1:result.mark.m1,
mark2:result.mark.m2
}
})
Is this possible in Mongoose?
I came across $setOnInsert, but not sure whether this fits here?
So if it fits, is there any equivalent workaround to use MongoDb's $setOnInsert? if not what approach I could use?
Yes, it's possible but that depends on the options set when defining your schema. You don't necessarily need to use the $setOnInsert operator when inserting a new record, the save() method on the model suffices.
The strict option ensures that values added to your model instance that were not specified in the schema gets saved or not to the db.
For example, if you had defined your schema like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var studentSchema = new Schema({
firstname: String,
lastname: String,
class: String
})
var Student = mongoose.model('Student', studentSchema);
var student= new Student({
_id: id,
firstname: result.fname,
lastname: result.lname,
class: result.class,
marks: {
mark1: result.mark.m1,
mark2: result.mark.m2
}
});
student.save(); // marks is not saved to the db
But if you set the strict option to false:
var studentSchema = new Schema({..}, { strict: false });
var student= new Student({
_id: id,
firstname: result.fname,
lastname: result.lname,
class: result.class,
marks: {
mark1: result.mark.m1,
mark2: result.mark.m2
}
});
student.save(); // marks is now saved to the db!!
NOTE: The strict option is set to false in mongoose v2 by default for backward compatibility. Set it to true and sleep peacefully. Do not set to false unless you have good reason.

Resources