What is the best way to hook to existing mongoose.model - node.js

I have a project with multiple self contained mongoose model files. I have another modelprovider which uses the model name and the request to perform an operation. I want to hook the operation to the pre of 'find'
model file
'use strict';
// load the things we need
var mongoose = require('mongoose');
var config = require('../../config/environment');
var auth_filter = require('../../auth/acl/lib/queryhook');
var modelProviders = require('../../auth/acl/lib/modelprovider');
var invoice_db = mongoose.createConnection(config.mongo.url + '/invoiceDB'); //connect to buyer DB
var path = require('path');
// define the schema for our invoice details model
var invoicedetailSchema = new Schema({
//SCHEMA INFO
});
var InvoiceModel = invoice_db.model('InvoiceDetail', invoicedetailSchema);
//REGISTER THE HOOKS TO THE MDOEL
auth_filter.registerHooks(InvoiceModel);
promise.promisifyAll(InvoiceModel);
promise.promisifyAll(InvoiceModel.prototype);
module.exports = InvoiceModel;
modelProviders().setModel(InvoiceModel.modelName, path.resolve(__dirname, __filename) );
I know the hooks to find and findOne works only at the schema level but i want to be done at the model level.
registerhooks
'use strict';
var hooks = require('hooks'),
_ = require('lodash');
var mongoose = require('mongoose');
exports.registerHooks = function( model) {
var Qry = mongoose.Query;
var query = model.find();
var Sch = mongoose.Schema;
var schema = model.schema
_.assign(model, hooks);
model.hook('find', mongoose.model.prototype.find)
model.pre('find', function(next){
console.log('hell')
return next()
})
console.log(model)
};
exports.registerHooks_ = function( model) {
var Qry = mongoose.Query;
var query = model.find();
var Sch = mongoose.Schema;
var schema = model.schema
_.assign(schema, hooks);
schema.hook('find', query)
schema.pre('find', function(next){
console.log('hell')
return next()
})
console.log(schema)
};
I know the documentation proposes to do the pre and post at the schema level but is there any way to use the hooks library or the hooker library to solve this problem.
The reason i want to keep it at the model level is I need to access the model name at the 'find' pre hook. If there is a way to do so then it will be awesome

Related

Imported mongoose model cannot perform operations

I have created a mongoose model in a file User.js:
var mongoose = require('mongoose');
exports.GetUser=function(conn){
var UserSchema = mongoose.Schema({
username: String,
age: Number
},{collection:"User",versionKey: false});
var usermodal = conn.modal("User",UserSchema);
return usermodal;
}
I am importing and using it in test.js file like this:
var user = require('./User.js');
var mongoose = require('mongoose');
var conn = mongoose.createConnection(\\connection string and other config here);
var userModal = user.GetUser(conn);
userModal.find({},(err, result)=>{
console.log(result); //prints undefined
});
The result comes undefined here. When I moved the model inside test.js, it started working and fetched data from the collection correctly. I cannot find what is the issue here. There are other models as well in User.js which I am exporting and using in the same way but they are also not working.
Please help me to find the issue and correct it. Thanks!

I tried mongoose find, why is [ ] being printed?

I tried to output the information stored in the db, but the result is only []. Where is the problem?
route/serch.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var crodata = require('../model/cro');
router.get('/',function (req,res,next) {
var ser = req.query.word; //namsan
crodata.find({tags:{$regex:ser}} , function(err, result) {
if(err) { console.log(err)}
console.log(result);
})
//res.render('serch',result)
});
module.exports = router;
/model/cro.js
const mongoose = require('mongoose')
var Schema = mongoose.Schema;
var croSchema = new Schema(
{ index:String,content:String,data:String,like:String,place:String,tags:String}
)
module.exports = mongoose.model('cro1',croSchema);
Information stored in db
{"_id":{"$oid":"5fe916d69d46ee5848393949"},
"index":"1",
"content":"Seoul Vibes.#namsan #fstopgear #breathbaselayer ",
"data":"2020-12-27",
"like":"946",
"place":"Seoul",
"tags":"['#namsan', '#nseoultower',]"}
Be sure that req.query.word property has a value, remember that req.query shape is based on user-controlled input (should be validated before trusting).
Beside that, you query look ok, but is good to know that, MongoDB must perform a collection scan, i.e. scan every document in a collection, to select those documents that match you query statement.
More about Regex and Index

i would like to query for a specific feature in a feature collection

var mongoose=require('mongoose');
var GeoJSON = require('mongoose-geojson-schema');
var db = require('./connection.js');
const Schema = mongoose.Schema;
const senuSchema = new Schema({
type:mongoose.Schema.Types.FeatureCollection,
name:String,
crs:Object,
features:Array
});
const model = db.model('senu', senuSchema, 'senu');
console.log('succefully made model');
model.findOne({name:'senu'},function(err,doc){
if (err){console.log(err);}
else{
console.log(doc);
}
});
The code gets a mondodb database connection then I create a model for the data I'm trying to retrieve but when I run it, i get the whole object.
I would like to query for a specific feature within the object which is in a features array in the object.

Querying result from mongoose using dynamic model.find

I need to find the results of a query with mongoose find({}) method in Node.js with a variable containing model name.
var adSchema = new Schema({ schema defination });
var Ad = mongoose.model('Ad', adSchema);
var variableName = 'Ad';
variableName.find({}).exec(function (err, adObj) {});
Is it possible or not?
Thanks in advance
You should be able to do that when calling model with just the name like so
mongoose.model('Ad').find({}).exec(function (err, adObj) {});
See here for the corresponding part of the official docs
Try this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var anySchema = new Schema({
fieldname: String
});
var Test = mongoose.model('Test', anySchema);
Test.find({}).exec(function(err,result){});

Hook to a specific Mongoose model query

I have self contained model in invoice.js
'use strict';
// load the things we need
var mongoose = require('mongoose');
var auth_filter = require('../../auth/acl/lib/queryhook');
var invoice_db = mongoose.createConnection(config.mongo.url + '/invoiceDB');
// PROMISE LIBRARY USED FOR ASYNC FLOW
var promise = require("bluebird");
var Schema = mongoose.Schema, ObjectId = Schema.Types.ObjectId;
// define the schema for our invoice details model
var invoicedetailSchema = new Schema({
//SCHEMA INFO
});
var InvoiceModel = invoice_db.model('InvoiceDetail', invoicedetailSchema);
// create the model for seller and expose it to our app
auth_filter.registerHooks(InvoiceModel);
module.exports = InvoiceModel;
I want to hook to the pre query for this model. I am trying to accomplish that using hooks but i am not successful with that. I am registering the hook using auth_filter file as below
'use strict';
var hooks = require('hooks'),
_ = require('lodash');
exports.registerHooks = function (model) {
model.pre('find', function(next,query) {
console.log('test find');
next();
});
model.pre('query', function(next,query) {
console.log('test query');
next();
});
};
What am I doing wrong? I want to keep the hooks separate so that I can call for a lot of different models.
Query hooks need to be defined on the schema, not the model. Also, there is no 'query' hook, and the query object is passed to the hook callback as this instead of as a parameter.
So change registerHooks to be:
exports.registerHooks = function (schema) {
schema.pre('find', function(next) {
var query = this;
console.log('test find');
next();
});
};
And then call it with the schema before creating your model:
var invoicedetailSchema = new Schema({
//SCHEMA INFO
});
auth_filter.registerHooks(invoicedetailSchema);
var InvoiceModel = invoice_db.model('InvoiceDetail', invoicedetailSchema);

Resources