Mongoose - Restrict the fields on referenced model - mongodb

I have users model that can hold multiple notifications. In the NotificationSchema the notifier holds users ID and it references the users model. When I execute the following query :
User.find().populate('notifications.notifier').exec(function(err,users){
//users[0].notifications[0].notifier
//I am getting all fields from the referenced user
//I don't want the whole document but some fields only
});
How can someone Limit / Restrict the fields that should be available while referencing to some model.
Here is the users model
var NotificationSchema =new Schema({
notifier : {type:Schema.Types.ObjectId, ref:'users'},
//How could I say :
//notifier : {type:Schema.Types.ObjectId, ref:'users', fields:['_id', 'name']}
//because I know what fields do I need from referenced model for this Schema.
__SOME__
__OTHER__
__FIELDS__
});
var UsersSchema = new Schema({
name : {given:String, middle:String, family:String}
email:String,
password:String,
notifications : [NotificationSchema]
});
var Users = mongoose.model('users', UsersSchema);
BTW, I do not have separate model for NotificationSchema.
If this feature is not available out of the box how could I implement it manually. Am I missing some docs? Please let me know the robust way of doing it.

I found it in mongoose docs
I found the answer in Field Selection Section of the documentation
User.find().populate('notifications.notifier', '_id name').exec(function(err, users) {
//users[0].notifications[0].notifier ^^^^^^^^^ HOW FUNNY
//Yes I am getting '_id' and 'name' fileds only
});

Related

How can I create a relation in Strapi if I don't know the id of the field?

I am creating a collection of judges and courthouses. Every judge will be assigned to one courthouse. I have set up my relation to be that courthouse has many judges
I am attempting to do this programmatically when the app loads. I have a function that is able to populate all the fields in judge except the relation to courthouse. My function uses the Strapi API like this
const judge = await strapi.query('judge').create({
name: data[i].name,
},
{
courthouse: data[i].courthouse_name // here is where I think the relation is created
}
)
I am passing in a string that has the name of courthouse, because I don't know the ID of the courthouse in the Courthouse collection.
My question is it possible to create a relation to another collection by anything other than an ID? How can I create a relation to a courthouse by its name?
I couldn't find a way around building a relationship between two models without the ID, so I created a custom solution using the Strapi lifecycle hooks
Essentially what I did I utilized the beforeCreate lifecycle hook to query and find the courthouse that matches the name like this:
// judges.js
async beforeCreate(result, data) {
const courthouse = await strapi.query('courthouse').find(
{courthouse_name:data.courthouse}
); // returns the courthouse that matches the name
result['courthouse'] = courthouse[0].id; // populates the relational field with the
// ID of the courthouse
}
The response object contained the courthouse's ID and I manipulated the data that is being sent to the create command like this:
const judge = await strapi.query('judge').create({
name: data[i].name,
courthouse: data[i].courthouse_name
})
The result is an object that looks like this:
{name: 'Garfield Lucas, courthouse: 7463987}

MongoDB pre save set field based on lookup logic

People register for an event. There are two collections in the database. One for new registrations coming in and one for the registrations of previous years. Both contain an email field as unique identifier.
I would like to know if its possible to check if a newly registered person has registered before in previous years. If so add a field, for example: returningCustomer: true. Otherwise add returningCustomer: false
I am using Mongoose and have a User model for new registrations. I don't have a model (yet) for previously registered users. Would that be neccesary? If it is possible to check if a person has registered before and a field can be added before saving, it might be handy to save the user to the returning customers collection immediatly as well.
I know it is possible to access the current document and collection using a pre save hook, but how about doing a lookup in another collection, write a bit of logic and add a field to the current document pre save?
userSchema.pre('save', function (doc, next) {
const exists = otherCollection.find({ email: doc.email });
exists ? doc.returningCustomer = true : doc.returningCustomer = false;
next();
});
You should have a model for the collection you want to lookup.
Then you can query the other collection before saving the current collection.
CurrentModel.pre('save', async function (next) {
const doc = await OtherModel.find({ field: this.field });
doc.length ? this.returningCustomer = false : this.returningCustomer = true;
next();
});

How do you set-up a mongoose column from schema A to have the values from a column from schema B?

I have
schema A:
let informationAssetsRow = new Schema({
infAss: {
type: String
})
Schema B
let informationAssetsSeverityEvaluationRow = new Schema({
Informationasset: {
type: String
}
})
For the sake of simplicity I have removed other attributes.
What I would like to do is:
Each time a document inserted in collection A. I want the value of infAss to be also inserted in Informationasset in column B.
From SQL perspective, this seems to be infAss of collection A should be set-up as an external key to schema B. I'm not sure I'm right.
However, in mongodb it's not clear if that is doable.
Any help?
You can create a post('save') hook on informationAssetsRow schema to achieve what you want.
Everytime a new document is inserted in collection A, post save hook will save new document into collection B.
Try this:
informationAssetsRow.post('save',function(doc){
informationAssetsSeverityEvaluationRow.create({
Informationasset : doc.infAss
})
})
Read more about Mongoose Post Hooks for detailed information.

Why I need to specify a name when I create a new model?

I'm just beginning learning MongoDB and Mongoose, I can't get the point of the first argument of model function. Why I need to specify a string as name, and what's its purpose?
// Schema
var CustomerSchema = mongoose.Schema({
name: String
});
// Model, that is the constructor
var Customer = mongoose.model('Customer', CustomerSchema);
// Instance, a particular customer
var john = new Customer({});
The lower-cased, pluralized version of the model name is used for the name of the MongoDB collection it's associated with (e.g. customers in this case).
It also allows your code to look up the model by name via mongoose.model('Customer').

How to store data inside mongodb

js and mongodb.I have created a model file named models like the one given below
User = new Schema({
username : String
, password : String
, created_at : Date
});
mongoose.model('User', User);
exports.defineModels = defineModels;
In app.js i have called the defineModels like this:
var models = require('./models'),
models.defineModels(mongoose, function() {
app.User = User = mongoose.model('User');
db = mongoose.connect(app.set('db-uri'));
})
I can't call save method directly on User or can I?
i want to save data in User what could be the function for the same.any answer will be appriciated
To do what you want, you should have something like this:
var user = new User({username: 'Name', password: 'unsecure'});
user.save();
There are a few things odd with your code, so I highly suggest going over a tutorial that uses express and mongoose to create a sample site (most likely you can find a blog).
Here is one I made: https://github.com/mathrawka/node-express-starter
Good luck!