using custom object ID with mongoose - node.js

I am working on a API.I am using mongo DB and mongoose as ORM tool with express. I want to use customer object id for my schema.
I want to implement CURD operation on the schema with customer id. The custom id can be anything for ex: 'someid' or a Number like 1.
The users can query the API using those Id's
I am using Model.create() method to insert and update() method to update and remove() method to delete and findById to find by id
The Schema is defined as
var mySchema = new Schema({
name : {type: String},
email: {type : String}
});
EDIT:
If the ID is not present then generate an auto id

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 access a referenced data with objectId of MongoDB in Flutter?

I'm new to Flutter. I used nodejs and MongoDB as Backend API. How do I access DataModel with ObjectId references in Nested Database in Flutter?
You can simply use populate function with find method in mongodb: Ref
Let's assume that there is userDeatils model which is referenced withing user model like this :
var user = new Schema({
name:String,
userdetails:{
type:mongoose.types.ObjectId,
ref:'userDetails'
}
});
Then You can Find data using Query like :
db.user.find({name:"Ram"}).populate('userdetails')
[DO VOTE TO THIS ANSWER, IF ITS HELPFUL TO YOU]

mongoose generating a children field using parent field

I am trying to create a family tree website using mongodb. upon creating a new family member, i only want to reference the parent (father) of the person and have mongoose automatically generate a children field in the person model. Here is the Person schema:
Person.add({
fullName: { type: String, initial:true, required: true,label: , index:true, },
parent: {type: Types.Relationship, ref:'Person'},
});
As you can see, upon creating a new person, I would want mongoose to automatically find all people in the Person model with the parent id matching the person I'm creating and generate an array of ids in the children field.
I have done some researches and found that Mongoose Virtuals can provide something like that but i have not found any documentation regarding querying the model to add to the virtual field. Thanks in advance!
You can create a post save hook in your Person schema model, and then find the people with parent id and create/update children array of that person.
use $addToSet instead of $push so that same childrens are not pushed more than once.
Try this:
PersonSchema.post('save', function(doc, next) {
this.findOneAndUpdate({_id : doc.parent},{$addToSet : { children : doc._id}})
next();
});
Read more about mongoose hooks for detailed information.

Mongoose Populate Returning null due to Schema design?

I'm stuck with mongoose populate returning null. I have a very similar situation to another question where it seems to we working just fine, perhaps with one important difference:
The model I'm referencing only exist as a subdocument to another model.
Example:
// The model i want to populate
Currency = new Schema({
code: String,
rate: Number
});
// The set of currencies are defined for each Tenant
// A currency belongs to one tenant, one tenant can have multiple currencies
Tenant = new Schema({
name: String,
currencies: [Currency]
});
Product = new Schema({
Name: String,
_currency: {type: ObjectId, ref: 'Currency'},
});
Customer = new Schema({
tenant: {type: ObjectId, ref: 'Tenant'},
products: [ Product ]
});
Then I export the models and use them in one of my routes where what I would like to do is something like
CustomerModel.find({}).populate('products._currency').exec(function(err, docs){
// docs[0].products[0]._currency is null (but has ObjectId if not usinn populate)
})
Which is returning null for any given product._currency but if I don't populate i get the correct ObjectId ref, which corresponds to an objectId of a currency embedded in a tenant.
I'm suspecting I need currencies to be stand-alone schema for this to work., Ie not just embedded in tenant, but that would mean I get a lot of schemas referencing each other.
Do you know if this is the case, or should my set-up work?
If this is the case, I guess I just have to bite the bullet and have multitude of collections referencing each other?
Any help or guidance appreciated!

is there a way to auto generate ObjectId when a mongoose Model is new'ed?

is there a way to declare a Model schema in mongoose so that when the model is new'ed the _id field would auto-generate?
for example:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectIdSchema = Schema.ObjectId;
var ObjectId = mongoose.Types.ObjectId;
var PersonSchema = new Schema({
_id: ObjectIdSchema,
firstName: {type: String, default: 'N/A'},
lastName: {type: String, default: 'N/A'},
age: {type: Number, min: 1}
});
var Person = mongoose.model('Person', PersonSchema);
at first, i thought great!, i'll just do
_id: {type:ObjectIdSchema, default: new ObjectId()}
but of course that doesn't work, because new ObjectId() is only called on initialize of schema. so calling new Persion() twice creates two objects with the same _id value.
so is there a way to do it so that every time i do "new Person()" that a new ObjectId() is generated?
the reason why i'm trying to do this is because i need to know the value of the new person's _id value for further processing.
i also tried:
var person = new Person({firstName: "Joe", lastName: "Baz"});
person.save(function(err, doc, num){
console.log(doc._id);
});
even then, doc doesn't contain the ObjectId. but if i look in the database, it does contain it.
p.s. i'm using mongoose 2.7.1
p.p.s. i know i can manually create the ObjectId when creating the person as such:
var person = new Person({_id: new ObjectId(), firstName: "Joe", lastName: "Baz"});
but i rather not have to import ObjectId and have to new it every time i want to new a Person. guess i'm used to using the java driver for mongodb, where i can just create the value for the _id field in the Model constructor.
Add the auto flag:
_id: {
type: mongoose.Schema.Types.ObjectId,
index: true,
required: true,
auto: true,
}
source
the moment you call var person = new Person();
person._id should give you the id (even if it hasn't been saved yet). Just instantiating it is enough to give it an id. You can still save it after, and that will store the id as well as the rest of the person object
Instead of:
_id: {type:ObjectIdSchema, default: new ObjectId()}
You should do:
_id: {type:ObjectIdSchema, default: function () { return new ObjectId()} }
Taken from the official MongoDB Manual and Docs:
_id
A field required in every MongoDB document. The _id field must have a
unique value. You can think of the _id field as the document’s primary
key. If you create a new document without an _id field, MongoDB
automatically creates the field and assigns a unique BSON ObjectId.
Source
ObjectID
ObjectIds are small, likely unique, fast to generate, and ordered.
ObjectId values consist of 12 bytes, where the first four bytes are a
timestamp that reflect the ObjectId’s creation. Specifically:
a 4-byte value representing the seconds since the Unix epoch, a 5-byte
random value, and a 3-byte counter, starting with a random value. In
MongoDB, each document stored in a collection requires a unique _id
field that acts as a primary key. If an inserted document omits the
_id field, the MongoDB driver automatically generates an ObjectId
for the _id field.
This also applies to documents inserted through update operations with
upsert: true.
MongoDB clients should add an _id field with a unique ObjectId.
Using ObjectIds for the _id field provides the following additional
benefits: in the mongo shell, you can access the creation time of the
ObjectId, using the ObjectId.getTimestamp() method. sorting on an _id
field that stores ObjectId values is roughly equivalent to sorting by
creation time. IMPORTANT While ObjectId values should increase over
time, they are not necessarily monotonic. This is because they:
Only contain one second of temporal resolution, so ObjectId values
created within the same second do not have a guaranteed ordering, and
Are generated by clients, which may have differing system clocks.
Source
Explicitly declaring _id:
When explicitly declaring the _id field, specify the auto option:
new Schema({ _id: { type: Schema.ObjectId, auto: true }})
ObjectId only - Adds an auto-generated ObjectId default if turnOn is true.
Source
TL;DR
If you create a new document without an _id field, MongoDB automatically creates the field and assigns a unique BSON ObjectId.
This is good way to do this
in model:
const schema = new Schema({ userCurrencyId:{type: mongoose.Schema.Types.ObjectId,
index: true,
required: true,
auto: true});

Resources