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

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")

Related

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 query documents in mongodb using mongoose

When i try to find a document like
const p1 = Profile.find()
console.log(p1) i should get all document in that collections but i'm getting different crap.
this is my simple schema in mongodb nodejs
const ProfileSchema = mongoose.Schema({
name: String,
age: Number,
subjects: [String],
late: Boolean
});
const Profile = mongoose.model('profile',ProfileSchema);
const profile1 = Profile.find()
console.log(profile1)
Use this -
Profile.find({}, function(err, profiles) {
console.log(profiles);
});
Refer this for more details - https://mongoosejs.com/docs/api.html#model_Model.find
const profile1 = await Profile.find({});
Since Mongoose supports async/await I would make the wrapping function async and call your find function using the await syntax.
Also make a point to pass in an empty object {} to your find function when you want to return all the documents in the collection.
More information here: https://mongoosejs.com/docs/api.html#query_Query-find

Node.js can not set default UUID with mongoose

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.

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

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.

Resources