Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Easily create a Mongoose Service for Feathersjs.

License

NotificationsYou must be signed in to change notification settings

feathersjs-ecosystem/feathers-mongoose

Repository files navigation

CIDependency StatusDownload Status

AFeathers database adapter forMongoose, an object modeling tool forMongoDB.

$ npm install --save mongoose feathers-mongoose

Important:feathers-mongoose implements theFeathers Common database adapter API andquerying syntax.

This adapter also requires arunning MongoDB database server.

API

service(options)

Returns a new service instance initialized with the given options.Model has to be a Mongoose model. See theMongoose Guide for more information on defining your model.

constmongoose=require('mongoose');constservice=require('feathers-mongoose');// A module that exports your Mongoose modelconstModel=require('./models/message');// Make Mongoose use the ES6 promisemongoose.Promise=global.Promise;// Connect to a local database called `feathers`mongoose.connect('mongodb://localhost:27017/feathers');app.use('/messages',service({ Model}));app.use('/messages',service({ Model, lean, id, events, paginate}));

Options:

  • Model (required) - The Mongoose model definition
  • lean (optional, default:true) - Runs queries faster by returning plain objects instead of Mongoose models.
  • id (optional, default:'_id') - The name of the id field property.
  • events (optional) - A list ofcustom service events sent by this service
  • paginate (optional) - Apagination object containing adefault andmax page size
  • whitelist (optional) - A list of additional query parameters to allow (e..g[ '$regex', '$populate' ])
  • multi (optional) - Allowcreate with arrays andupdate andremove withidnull to change multiple items. Can betrue for all methods or an array of allowed methods (e.g.[ 'remove', 'create' ])
  • overwrite (optional, default:true) - Overwrite the document when update, making mongoose detect is new document and trigger default value for unspecified properties in mongoose schema.
  • discriminators (optional) - A list of mongoose models that inherit fromModel.
  • useEstimatedDocumentCount (optional, default:false) - UseestimatedDocumentCount instead (usually not necessary)
  • queryModifier (optional) - A function that takes in the raw mongoose Query object and params, which modifies all find and get requests unless overridden. (see Query Modifiers below)
  • queryModifierKey (optional, default:'queryModifier') - The key to use to get the override query modifier function from the params. (see Query Modifiers below)

Important: To avoid odd error handling behaviour, always setmongoose.Promise = global.Promise. If not available already, Feathers comes with a polyfill for native Promises.

Important: When settinglean tofalse, Mongoose models will be returned which can not be modified unless they are converted to a regular JavaScript object viatoObject.

Note: You can get access to the Mongoose model viathis.Model inside ahook and use it as usual. See theMongoose Guide for more information on defining your model.

params.mongoose

When making aservice method call,params can contain amongoose property which allows you to modify the options used to run the Mongoose query. Normally, this will be set in a beforehook:

app.service('messages').hooks({before:{patch(context){// Set some additional Mongoose options// The adapter tries to use these settings by defaults// but they can always be changed herecontext.params.mongoose={runValidators:true,setDefaultsOnInsert:true}}}});

Themongoose property is also useful for performing upserts on apatch request. "Upserts" do an update if a matching record is found, or insert a record if there's no existing match. The following example will create a document that matches thedata, or if there's already a record that matches theparams.query, that record will be updated.

Using thewriteResult mongoose option will return the write result of apatch operation, including the _ids of all upserted or modified documents. This can be helpful alongside theupsert flag, for detecting whether the outcome was a find or insert operation. More on write results is available in theMongo documentation

constdata={address:'123',identifier:'my-identifier'}constparams={query:{address:'123'},mongoose:{upsert:true,writeResult:true}}app.service('address-meta').patch(null,data,params)

Example

Here's a complete example of a Feathers server with amessages Mongoose service.

$ npm install @feathersjs/feathers @feathersjs/errors @feathersjs/express @feathersjs/socketio mongoose feathers-mongoose

Inmessage-model.js:

constmongoose=require('mongoose');constSchema=mongoose.Schema;constMessageSchema=newSchema({text:{type:String,required:true}});constModel=mongoose.model('Message',MessageSchema);module.exports=Model;

Then inapp.js:

constfeathers=require('@feathersjs/feathers');constexpress=require('@feathersjs/express');constsocketio=require('@feathersjs/socketio');constmongoose=require('mongoose');constservice=require('feathers-mongoose');constModel=require('./message-model');mongoose.Promise=global.Promise;// Connect to your MongoDB instance(s)mongoose.connect('mongodb://localhost:27017/feathers');// Create an Express compatible Feathers application instance.constapp=express(feathers());// Turn on JSON parser for REST servicesapp.use(express.json());// Turn on URL-encoded parser for REST servicesapp.use(express.urlencoded({extended:true}));// Enable REST servicesapp.configure(express.rest());// Enable Socket.io servicesapp.configure(socketio());// Connect to the db, create and register a Feathers service.app.use('/messages',service({  Model,lean:true,// set to false if you want Mongoose documents returnedpaginate:{default:2,max:4}}));app.use(express.errorHandler());// Create a dummy Messageapp.service('messages').create({text:'Message created on server'}).then(function(message){console.log('Created message',message);});// Start the server.constport=3030;app.listen(port,()=>{console.log(`Feathers server listening on port${port}`);});

You can run this example by usingnode app and go tolocalhost:3030/messages.

Querying, Validation

Mongoose by default gives you the ability to addvalidations at the model level. Using an error handler like the one thatcomes with Feathers your validation errors will be formatted nicely right out of the box!

For more information on querying and validation refer to theMongoose documentation.

$populate

For Mongoose, the special$populate query parameter can be used to allowMongoose query population.

Important:$populate has to be whitelisted explicitly since it can expose protected fields in sub-documents (like the user password) which have to be removed manually.

constmongoose=require('feathers-mongoose');app.use('/posts',mongoose({  Model,whitelist:['$populate']});app.service('posts').find({query:{$populate:'user'}});

Error handling

As of v7.3.0, the original Mongoose error can be retrieved on the server via:

const{ERROR}=require('feathers-mongoose');try{awaitapp.service('posts').create({value:'invalid'});}catch(error){// error is a FeathersError// Safely retrieve the original Mongoose errorconstmongooseError=error[ERROR];}

Discriminators (Inheritance)

Instead of strict inheritance, Mongoose usesdiscriminators as their schema inheritance model.To use them, pass in adiscriminatorKey option to your schema object and useModel.discriminator('modelName', schema) instead ofmongoose.model()

Feathers comes with full support for mongoose discriminators, allowing for automatic fetching of inherited types. A typical use case might look like:

varmongoose=require('mongoose');varSchema=mongoose.Schema;varPost=require('./post');varfeathers=require('@feathersjs/feathers');varapp=feathers();varservice=require('feathers-mongoose');// Discriminator key, we'll use this later to refer to all text postsvaroptions={discriminatorKey:'_type'};varTextPostSchema=newSchema({text:{type:String,default:null}},options);// Note the use of `Post.discriminator` rather than `mongoose.discriminator`.varTextPost=Post.discriminator('text',TextPostSchema);// Using the discriminators option, let feathers know about any inherited models you may have// for that serviceapp.use('/posts',service({Model:Post,discriminators:[TextPost]}))

Without support for discriminators, when you perform a.get on the posts service, you'd only get backPost models, notTextPost models.Now in your query, you can specify a value for your discriminatorKey:

{_type:'text'}

and Feathers will automatically swap in the correct model and execute the query it instead of its parent model.

Collation Support

This adapter includes support forcollation and case insensitive indexes available in MongoDB v3.4. Collation parameters may be passed using the specialcollation parameter to thefind(),remove() andpatch() methods.

Example: Patch records with case-insensitive alphabetical ordering

The example below would patch all student records with grades of'c' or'C' and above (a natural language ordering). Without collations this would not be as simple, since the comparison{ $gt: 'c' } would not include uppercase grades of'C' because the code point of'C' is less than that of'c'.

constpatch={shouldStudyMore:true};constquery={grade:{$gte:'c'}};constcollation={locale:'en',strength:1};students.patch(null,patch,{ query, collation}).then( ...);

Example: Find records with a case-insensitive search

Similar to the above example, this would find students with a grade of'c' or greater, in a case-insensitive manner.

constquery={grade:{$gte:'c'}};constcollation={locale:'en',strength:1};students.find({ query, collation}).then( ...);

For more information on MongoDB's collation feature, visit thecollation reference page.

Mongo-DB Transaction

This adapter includes support to enable database transaction to rollback the persisted records for any error occured for a api call. This requiresMongo-DB v4.x installed andreplica-set enabled.

Start working with transaction enabled by adding the following lines inapp.hooks.js or<any-service>.hooks.js.

constTransactionManager=require('feathers-mongoose').TransactionManager;constisTransactionEnable=process.env.TRANSACTION_ENABLE||false;constskipPath=['login'];letmoduleExports={before:{all:[],find:[],get:[],create:[when(isTransactionEnable,asynchook=>TransactionManager.beginTransaction(hook,skipPath))],update:[when(isTransactionEnable,asynchook=>TransactionManager.beginTransaction(hook,skipPath))],patch:[],remove:[]},after:{all:[],find:[],get:[],create:[when(isTransactionEnable,TransactionManager.commitTransaction)],update:[when(isTransactionEnable,TransactionManager.commitTransaction)],patch:[],remove:[]},error:{all:[],find:[],get:[],create:[when(isTransactionEnable,TransactionManager.rollbackTransaction)],update:[when(isTransactionEnable,TransactionManager.rollbackTransaction)],patch:[],remove:[]}};module.exports=moduleExports;

Query Modifiers

Sometimes it's important to use an unusual Mongoose Query method, likespecifying whether to read from a primary or secondary node, but maybe only for certain requests.

You can access the internal Mongoose Query object used for a find/get request by specifying the queryModifier function. It is also possible to override that global function by specifying the function in a requests params.

// Specify a global query modifier when creating the serviceapp.use('/messages',service({  Model,queryModifier:(query,params)=>{query.read('secondaryPreferred');}}));app.service('messages').find({query:{ ...},}).then((result)=>{console.log('Result from secondary:',result)});// Override the modifier on a per-request basisapp.service('messages').find({query:{ ...},queryModifier:(query,params)=>{query.read('primaryPreferred');}}).then((result)=>{console.log('Result from primary:',result)});// Disable the global modifier on a per-request basisapp.service('messages').find({query:{ ...},queryModifier:false}).then((result)=>{console.log('Result from default option:',result)});

Note: Due to replication lag, a secondary node can have "stale" data. You should ensure that this "staleness" will not be an issue for your application before reading from the secondary set.

Contributing

This module is community maintained and open for pull requests. Features and bug fixes should contain

  • The bug fix / feature code
  • Tests to reproduce the bug or test the feature
  • Documentation updates (if necessary)

To contribute, fork and clone the repository. To run the tests, a MongoDB v4.0.0 server is required. If you do not have a MongoDB server running you can start one with:

npm run mongodb

The command needs to stay open while running the tests with

npm test

License

MIT

Authors

About

Easily create a Mongoose Service for Feathersjs.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors39


[8]ページ先頭

©2009-2025 Movatter.jp