Get a tree with MongoDB query (mongoose) - node.js

Is there any easy way to get a tree in mongoose? Let's consider following example:
categorySchema = new mongoose.Schema({
name : {type: String, required: true},
parent : {type: Schema.Types.ObjectId, ref: 'Category'}
})
I have a category that can have a lot of children (sub-categories), and these children can have a lot of children (sub-sub-categories) and so on...
As far as it's quite easy to build such structure and modify it, it's quite hard for me to retrieve that structure.
I did it in very bad way scanning the collection recursively, but I guess there can be a better way to do that.
In SQL it's quite easy to achieve that and I am wondering if there is a good way to do that in mongodb.
Note: This schema may be changed if needed.

Related

Making a MongoDB userSchema with specific privileges on each region

I have to make a page for entering some data about people on specific regions. Each user will have prvileges on a specific region.
So I will make two collections into a DB. One for the users and one for the regions.
The users will have access only to one region (or in some cases to more) and specific acceses, like read or write, or read&write, and so on.
How can I model my schema so I can add more regions?
That's how I did it:
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
let userSchema = new mongoose.Schema({
username:
{type: String,
unique: true
},
password: String,
privileges:
{
regiune: [Number],
read: [Number],
write: [Number],
edit: [Number]
}
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
but I don't know how I should edit this model so it can have multiple regions with different privileges.
For regular users they might have one region with read, write and edit, let's say. But if I want another user to have access to region x with read, write privileges and region y with write privileges I won't be able to do it using this schema.
So how should I edit this? (also, I'm a beginner in DBs so if there is another better way to set privileges please let me know)
Thanks!
Actually, since the privileges field belongs to each user, you can easily have multiple regions with different privileges
Turn privileges into an array and each particular permission into a number and you have it!
privileges:
[{
regiune: Number,
read: Number,
write: Number,
edit: Number
}]
An array of objects is the idiomatic way to model dependent objects in Mongo. People generally recommend not having an unbounded array as subdocument, but I bet your list of regions is relatively finite.
You will probably want to introduce some mechanism for ensuring that you have unique regiunes in the array. Mongo 4.10 introduced a plugin for this: https://www.npmjs.com/package/mongoose-unique-array that you can use like this:
privileges:
[{
regiune: { type: Number, unique: true },
read: Number,
write: Number,
edit: Number
}]
If you wanted to access your permissions as an object, by key: region1, region3, etc. Then you might declare privileges as a mixed type, meaning it can be any arbitrary json structure (but you lose type information). Or you might make it a separate model, collection with a back ref to the user object. The user object could also have a list of references to this new model (but it would again be an array and not an object).

Should I create New Schema Model file for every route OR use already created Schema?

Suppose I have a User Schema which has around 30 fields, and other 3 schemas also.
UserSchema.js
user_schema = new Schema({
user_id: { type: String},
.........//30 properties
});
ctrs_schema = new Schema({
.........10 properties
});
ids_schema = new Schema({
.........5 properties
});
comments_schema = new Schema({
.........10 properties
});
Now I am writing a route which will change the gender of the user, Now in order to do it I can use UserSchema.js but that will load all of the schemas into my route, whereas if I would have created a new file which had only one schema with two fields, then all schemas will not get loaded into the memory for the route.
UserGenderSchema.js
gender_schema = new Schema({
user_id: { type: String},
gender: { type: String}
});
I know there are pros and cons of both of the ways
Pros -
I have to edit only in single file if I would have to change something
for any field.
Cons -
All Schemas are Loading for all routes which are unnecesary. Memory
Wastage.
Will, there be any less memory usage between both of the ways on the threads?
Can anyone Please tell me which architecture will be better or what you are implementing in your project and why?
Thanks
It's better to keep user related fields in just one schema, cause mongo has been there because of its non-relational structure and it gained its performance by keeping relational structures away, so if you create a schema for each field and then create a reference in each of them to point out to the user they are related to, you are kind of using mongo to build a heavily relational structure and mongo is not good as it should be in this situation, so if later on your application you want to somehow show all the information of the user or try to update multiple fields of user or try to show more information of the user in one of your routes or something, you will end up having some serious performance issues. as a conclusion, the cost of loading all the schema to touch only one field is not as much as the cost of breaking down your data structure.

How to handle creation of referenced documents in Mongoose and Node?

I have a Node.js API method that creates a Track document and then creates Task document (which has DBRef to a Track to work on) to actually convert and upload it to s3 (specific operations doesn't really matter). I use Mongoose to perform operations on my MongoDB.
So my question is there any way to avoid having "stalled" tracks that have Track document created and no Task for them? Creating a Task without Track is fine though, but in that case we don't have DBRef until we create a Track document and then update a Task document which may fail due to server restart or something.
In traditional RDBMS that kind of problem is easy to solve since I would do that in a single transaction.
Thanks in advance.
Update:
My schemas look like that:
var Track = new Schema({
name: String,
...
});
var Task = new Schema({
track: {type: Schema.Types.ObjectId, ref: 'Track'},
created: {type: Date, default: Date.now}
});

How do i create a schema for a geojson data in mongoose?

I am working with mapbox api and I want to maintain a geojson data on my server itself so that i can fetch the data from this file to put pins on the map. if any one can tell me about the correct schema that has to be used for a geojson data then it would be really a great help for me.
Here is the simple schema for one Point. and remember in mongo DB you have save [lon, lat]. in contrast to common pratice where latitude is mentioned first.
{
type : {type: String, default: 'Point'},
coordinates: {type: [Number]}
}

Implementing manual linkage/reference in mongoose

http://docs.mongodb.org/manual/reference/database-references/#DatabaseReferences-SimpleDirect%2FManualLinking
For nearly every case where you want to store a relationship between two documents, use manual references. The references are simple to create and your application can resolve references as needed.
As it has been indicated in the mongodb reference document it seems to be more reasonable to use manual linkage / reference rather than using the DBRef like this :
stories : [{ type: Schema.ObjectId, ref: 'Story' }]
Implementing the relations via DBref is quite simple as it seems. Apart from that I could not find a reliable resource on how to implement manual reference most efficiently in a schema. Proposals:
stories : [{ type: Schema.ObjectId}] OR
stories : [{ type: Number] OR
stories : [{ type: String]
How the manual reference should be implemented? It would be much appreciated an example of insertion as well.
Implementing this will depend on which library you use in which environment.
Here is a nice example for mongoose in node.js:
https://mongoosejs.com/docs/populate.html

Resources