Node.js can not set default UUID with mongoose - node.js

I was trying to define a default UUID in mongoose / Node.js / Express for my
_id field in my Schema Model...
/**Demonstrator
*
*/
var mongoose = require('mongoose')
var uuid = require('node-uuid')
require('mongoose-uuid2')(mongoose);
var Schema = mongoose.Schema;
require('mongoose-long')(mongoose);
var Status = require('./Status');
var StatusSchema = Status.Schema;
var SchemaTypes = mongoose.Schema.Types;
const uuidv4 = require('uuid/v4');
var UUID = mongoose.Types.UUID;
var DemonstratorSchema = new Schema({
//_id: SchemaTypes.Long;
_id: { type: String, default: uuidv4()},
id2: SchemaTypes.Long,
Test: String,
})
module.exports = mongoose.model("Demonstrator", DemonstratorSchema);
console.log("DemonstratorSchema created!");
I was also trying to write an own function like in this post:
Using UUIDs in mongoose for ObjectID references, but this didnt work either... it just won't create a default generated UUID with mongoose in my database, why?
EDIT: I just found out, it creates a UUID or String field with a 32byte UUID value, I just wasn't able to do this in the mongo shell directly, although I thought my Schema kind of enforces this, but its logical that this was nonsense, because the mongo Shell is not aware of anything of my backend constraints ;) sorry about that.... but is it also safe to assume, that anything coming from an REST API endpoint (POST) that is generated and saved in my backend, will have automatically created UUID?
And what is recommended to use as UUID version? v1? or rather v4 or even v5?

The default property should be a function that returns a string (in your case, a UUIDv4 value).
That's not what your schema provides, though:
_id: { type: String, default: uuidv4()}
That declaration will run the uuidv4 function, which returns a string, and use that string as the default. It's similar to this:
_id: { type: String, default: 'FA6281FF-5961-4F2F-8270-D6AB9954410D'}
Instead, pass it a reference to the uuidv4 function:
_id: { type: String, default: uuidv4 }
That way, each time a default value is required, Mongoose will call that function, which will return a new UUID every time.

Related

Mongoose schema + nodejs

I'm kinda new in mongodb and i'm in trouble
I can't reach a data from my mongo database
const mongoose = require('mongoose');
const Team = new mongoose.Schema({
name: String,
});
const MatchsSchema = new mongoose.Schema({
begin_at: Date,
number_of_games: Number,
name: String,
tournament: {
name: String,
},
opponents: {
type: [Team],
default: undefined
},
});
const Matchs = mongoose.model('matchs', MatchsSchema);
module.exports = Matchs;
I am trying to access with this code witch is return my "data" :
console.log(element.opponents[0]);
data returned
but when i want to access with .name the value is undefined
console.log(element.opponents[0].name);
database schema : db
I have an collection named "teams" in my db.
What is the problems ? I think i'm not that far...
It might be an overlook but try...
console.log(element.opponents[0].opponent.name);
db answer
My schema was not correct, with a modification that worked fine

Mongoose $pull not removing embedded sub-document by ObjectId [duplicate]

Is there a function to turn a string into an objectId in node using mongoose? The schema specifies that something is an ObjectId, but when it is saved from a string, mongo tells me it is still just a string. The _id of the object, for instance, is displayed as objectId("blah").
You can do it like so:
var mongoose = require('mongoose');
var id = mongoose.Types.ObjectId('4edd40c86762e0fb12000003');
You can use this also
const { ObjectId } = require('mongodb');
const _id = ObjectId("4eb6e7e7e9b7f4194e000001");
it's simplest way to do it
You can do it like this:
var mongoose = require('mongoose');
var _id = mongoose.mongo.BSONPure.ObjectID.fromHexString("4eb6e7e7e9b7f4194e000001");
EDIT: New standard has fromHexString rather than fromString
Judging from the comments, you are looking for:
mongoose.mongo.BSONPure.ObjectID.isValid
Or
mongoose.Types.ObjectId.isValid
var mongoose = require('mongoose');
var _id = mongoose.mongo.ObjectId("4eb6e7e7e9b7f4194e000001");
I couldn't resolve this method (admittedly I didn't search for long)
mongoose.mongo.BSONPure.ObjectID.fromHexString
If your schema expects the property to be of type ObjectId, the conversion is implicit, at least this seems to be the case in 4.7.8.
You could use something like this however, which gives a bit more flex:
function toObjectId(ids) {
if (ids.constructor === Array) {
return ids.map(mongoose.Types.ObjectId);
}
return mongoose.Types.ObjectId(ids);
}
Just see the below code snippet if you are implementing a REST API through express and mongoose. (Example for ADD)
....
exports.AddSomething = (req,res,next) =>{
const newSomething = new SomeEntity({
_id:new mongoose.Types.ObjectId(), //its very own ID
somethingName:req.body.somethingName,
theForeignKey: mongoose.Types.ObjectId(req.body.theForeignKey)// if you want to pass an object ID
})
}
...
Hope it Helps
If you want to use schema
const yourSchemma = new Schema({
"customerId": {
type: mongoose.Types.ObjectId,
required: true
}
});
If you want to use ObjectId a lot and don`t want to use mongoose.types.ObjectId, you can destructure your declaration:
const {
Types: { ObjectId: ObjectId },
} = require("mongoose");
const id=ObjectId("4edd40c86762e0fb12000003")

how to use the value of an item in a mongoose schema

I want to get the value of item in a schema and use it in the same schema.
e.g Have a
const mongoose = require("mongoose");
const TestSchema = new mongoose.Schema({
appellant: String,
respondent: String,
title: `${this.appellant} V. ${this.respondent}`,
});
module.exports = mongoose.model("Test", TestSchema);
Usually, a virtual schema is used for instances such as this. It allows you to utilize the data in a particular format, without persisting it and creating redundant data.
In your case, it would look something like this:
TestSchema.virtual('title').get(function () {
return this.appellant + ' V. ' + this.respondent
});

How to define a nested schema in mongoose?

My mongo record is like this:
{
"_id":{"$oid":"5550b6de437f572112a29f1a"},
"cv_count":177732,
"gender_info": {"male_count": 50, "female_count": 32}
"stability_info_list":[{"ratio":8.802558610369414e-05,"total_count":34081,"years":0},{"ratio":5.868372406912943e-05,"total_count":34081,"years":1}],
"zhineng_id":"IT Manager"
}
I write the schema like this:
var ZhinengGenderSchema = new Schema({
male_count: Number,
female_count: Number
});
var ZhinengStabilitySchema = new Schema({
ratio: Number,
total_count: Number,
years: Number
});
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: ZhinengGenderSchema,
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
But I got this excetion:
TypeError: Undefined type `undefined` at `gender_info`
Did you try nesting Schemas? You can only nest using refs or arrays.
so mongoose doesn't support nest schemas? But my database has already been there, I cannot change, so how can I define my schema?
Just don't create a new schema for the subdocuments and you should be fine, i.e.:
var ZhinengGenderSchema = {
male_count: Number,
female_count: Number
};
var ZhinengStabilitySchema = {
ratio: Number,
total_count: Number
years: Number
};
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: ZhinengGenderSchema,
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
With mongoose you can define nesting (embedded) schemas in Array, like this:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var bookSchema = new Schema({
value: { type: String }
});
var authorSchema = new Schema({
books: [bookSchema]
});
Or by reference
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = mongoose.Schema.Types.ObjectId;
var auhtorSchema = new Schema({
book: { type: ObjectId, ref: 'Book'}
});
You may choose what is more appropriate for you
As far as I know, this is due to a current limitation of Mongoose. You cannot
declare a schema field to include a single sub-document: you have to use an array, instead. See this: https://github.com/Automattic/mongoose/pull/585
You can set up later the proper business logic in order to ensure that only one sub-element will be added.
Try this:
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: [ZhinengGenderSchema],
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
This way, each sub-document has got its own _id in MongoDB (even though it does not lie in a specific collection). See more: http://mongoosejs.com/docs/subdocs.html
You could also prefer something like this:
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: [{male_count: Number, female_count: Number}],
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
In this case, you nest a schema inside another. The single gender_info element does not have the dignity of a document.

Mongoose error: nesting Schemas

I have a question about nesting Mongoose schema.
Here is a simple code snippet
var aSchema = new Schema({bar: String});
var bSchema = new Schema({a: aSchema, foo: String});
var cSchema = new Schema({as: [aSchema], foo:String});
This will throw TypeError on bSchema: TypeError: Undefined type at 's' Did you try nesting Schemas? You can only nest using refs or arrays., but works fine for cSchema.
Just want to ask why bSchema does not work. Cannot find explanation in Mongoose doc. Thanks.
MongoDB is not a relational database. This can cause confusion for some who are used to the RDBS model (I still get tripped up occasionally...but I'm really not a DB guy).
Oftentimes, you'll find it beneficial to reference other documents in your Mongo entities. Mongoose schemas provide a very simple and effective way to do this that feels very relational.
When defining a schema that will store a reference to a different type of document, you define the relevant property as an object with a type and a ref. Typically when defining schema properties, you can simply say: a: Number; however, Mongoose provides many different options for a schema property other than type:
a: {
type: Number,
required: true
}
Setting required: true will prevent us from saving a document where the a property is not present.
Once you understand how to define your schemas with object definitions, you can leverage Mongoose's population mechanic:
a: {
type: Mongoose.Schema.ObjectId,
ref: 'a'
}
This tells Mongoose to store the ObjectId (a Mongoose-specific identifier) of a specific a document as the a property of our schema. Still following me?
When setting this property on a Mongoose document, you can simply say: doc.a = myA. When you go to save doc, Mongoose will automagically make the conversion and only store the ID in your database.
When retrieving a document that references another schema, you'll need to populate. I won't go into that, but its pretty simple - check out the documentation.
I was facing this issue as I was completely new to the MongoDB. Later I found we need to use the relationship as below with the help of Mongoose.
Below is my country schema.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var CountrySchema = new Schema({
name: { type: String, required: true },
activeStatus: Boolean,
createdOn: Date,
updatedOn: Date
});
And I can use this schema in my State schema as follows.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var StateSchema = new Schema({
name: { type: String, required: true },
country: {type: ObjectId, ref: "Country"},
activeStatus: Boolean,
createdOn: Date,
updatedOn: Date
});
Here I am using pointing to my other schema with the help of ref.

Resources