DbRef with Mongoose - mongoose-dbref or populate? - mongodb

I have the following 2 schemas:
Company Event:
var companyEventSchema = new Schema({
name : String,
description
date : Date,
attendees : [ { type : Schema.ObjectId, ref : 'Member' } ],
]});
And Member
var memberSchema = new Schema({
name : String,
emailAddress: String,
password :String,
created: { type: Date, default: Date.now }
});
Is the way i've ref'd Member from companyEventSchema correct?
I'm trying to do something a long the lines of a dbref.
I saw theres a separate project for that though... mongoose-dbref
However, the mongoose docs say the above provides "dbref like functionality"
Which would be more efficient?

You only need to use an actual DBRef (and mongoose-dbref) for the case where a field can contain ObjectIds that reference documents in potentially more than one collection. A DBRef is a tuple of an ObjectId, a collection name, and an optional database name.
Mongoose ref: fields, however, contain just an ObjectId and it's the Mongoose schema that defines what one collection the ObjectIds reference.
So Mongoose ref: fields are more efficient and should always be used unless you need the multi-collection reference support that DBRef provides.

Related

mongodb - understanding references ids and ObjectId - which format to use?

var publisherSchema = Schema({
_id : Number,
name : String,
founded : Number,
books : [{ type: Schema.Types.ObjectId, ref: 'Book' }]
});
var bookSchema = Schema({
_id : Number,
title : String,
author : [{type: String}],
pages: Number,
language: String
});
var Book = mongoose.model('Book', bookSchema);
var Publisher = mongoose.model('Publisher', publisherSchema);
Trying to understand ObjectId: the type for books as listed as Schema.Types.ObjectId. Objectids are generated by Mongodb automatically.
If I add ids to the book array manually, type will be just strings. Do I need to somehow also generate Objectids saved in the books array so when I make a query (findById) I will find it or is it enough if I just add those id's as strings?
I read in another post its better to generate ObjectIds and not just strings to reduce space. Im confused by this as I read that they normally generated by mongodb. If I can (and should) generate them for ids -how to?
When I make a reference
books : [{ type: Schema.Types.ObjectId, ref: 'Book' }]
that is just for the developer to know that the id's are suppose to belong to the books collection, there is no internal linking functionality to the books collection from the publisher collection?!
Thanks!!

ref to filed of collection instead of collection mongodb

I have a schema like this
const Schema1 = new Schema({
field11: String,
field12: [
{ _id: Schema.Types.ObjectId,
title: String
}
]
})
and another schema which has a field to reference to filed of the first collection as below
const Schema2 = new Schema({
field21: String,
field22: [
{_id: {type: Schema.Types.ObjectId},
{ref: 'Schema1.filed12'}
]
})
I need to populate field22 in schema2. How do I need to do it.
The below query doesn't work for me.
Schema2.find(field21).populate('Schema1.field12')
According to the documentation:
The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _ids we store here must be document _ids from the Story model.
You are attempting to store non-id fields as a reference that should point to subdocuments that are nested in an array of your Schema1 model. This simply doesn't work.

Mongoose query document by field value and subdocument field value

I'm using mongoose and trying to get document by specific value of field on it and subdocument field's specific value. I dig a lot but I was unable to find anything matching - I am also new to MongoDb.
So my schema looks like :
messageSchema = Schema candidateId: {type: string},
template: {type: Schema.Types.ObjectId, ref: 'MessageTemplate'},
messageTemplate = Schema name:{type: string}, isActive:{type: boolean}
So I want to get all messages that have certain candidateId and messageTemplate.isActive equal to true.
I couldn't figure out query so I am doing work around like this
Message.find({candidateId: candidateId})
.populate('template')
.then(res => res.fileter(message => message.template.isActive)
It's working but I'm guessing it's possible to create better query, any help will be great.

Mongoose query return null

I can't seem to get a response from mongodb. I am using node.js and mongodb with the help of mongoose.
In my node.js app I have
mongoose.connect('mongodb://localhost:27017/myDB');
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var BlogPost = new Schema({
author : ObjectId,
title : String,
slug : { type: String, lowercase: true, trim: true },
content : String,
summary : String,
date : Date
})
var BlogModel = mongoose.model('BlogPost', BlogPost);
BlogModel.find({}, function(docs){
console.log(docs);
});
If I type show dbs in the mongo shell I get
admin (empty)
myDB 0.203125GB
local (empty)
test (empty)
db.blogmodel.find() returns :
{ "_id" : ObjectId("50108d3df57b0e3375a20479"), "title" : "FirstPost" }
and yes I do have mongod running.
Fixed Solution
var BlogModel = mongoose.model('blogmodel', BlogPost, 'blogmodel');
It works because its (model name, schema name, collection name)
Mongoose pluralizes model names so it's running find on the "blogposts" collection instead of "blogpost". That said, your query in the mongo shell is on the "blogmodel" collection. In that case:
var BlogModel = mongoose.Model("BlogModel", ..)
or pass the collection name as the third param:
var BlogModel = mongoose.model("BlogPost", schema, "blogmodel")
The first parameter to your BlogModel.find callback is err, the second parameter is docs. So your code should be:
BlogModel.find({}, function(err, docs){
console.log(docs);
});
For anyone still experiencing this issue even after checking the accepted answer – make sure your database connection url contains the database name, e.g. for database name myDB...
mongoose.connect(`mongodb://localhost:27017/myDB`)
I'd forgotten it and my mongoose searches were all returning null or empty arrays.
I experienced similar error yesterday, in my case error was caused by data imported to mongo. After I used mongoimport key _id was stored as string instead of ObjectId. When I was querying data in mongo everything works well, but in Mongoose when I was trying find something by _id it always returned null or empty Array. I hope that info might by useful for someone.

Using a selfdefined ObjectId and avoiding double entries in Mongoose

I am getting JSON objects through an external API in node.js and want to store them in MongoDB. I defined a model like this:
var Product = new Schema({
id: ObjectId,
name: String});
And now I'm trying to store an object:
JSONProduct = { id: 1234, name: 'The Foo Bar' };
product = new Product(JSONProduct);
product.save();
The object is stored fine in the "products" collection, but the id from the JSONProduct is replaced by a MongoDB created value:
{ "id" : ObjectId("119894980274616772006500"), "name" : "The Foo Bar" }
The main reason why I want to use my Product id over the MongoDB created one is, that I want to prevent duplicate entries for products. I get the JSON Product objects through a cronjob triggered call on an external API, including already existing ones. Maybe there is another, better way to do this?
You are defining an field as an ObjectID, but you are assigning a Number to it. To create an ObjectID you need to do something like:
new ObjectId('something');
However, in your case this is probably not the best idea. Define your model like this:
var Product = new Schema({
external_id: {type: Number, unique: true},
name: {type: String},
});
You can specify unique on a field to create a unique index for that field.
In the question you've mentioned,
The object is stored fine in the "products" collection, but the id from the JSONProduct is replaced by a MongoDB created value:
{ "id" : ObjectId("119894980274616772006500"), "name" : "The Foo Bar" }
But I think the it is created as:
{ "_id" : ObjectId("119894980274616772006500"), "name" : "The Foo Bar" }
Also, you can pass in your product id to field by name "_id", then mongo will not create any separate IDs and it'll not accept duplicate values and it'll have indexing automatically for that field.
But make sure you push unique values of product id to _id.