简体   繁体   English

如何在 ES6 / ES2015 中编写 Mongoose 模型

[英]How to write a Mongoose model in ES6 / ES2015

I want to write my mongoose model in ES6.我想用 ES6 编写我的猫鼬模型。 Basically replace module.exports and other ES5 things wherever possible.基本上尽可能地替换module.exports和其他 ES5 东西。 Here is what I have.这是我所拥有的。

import mongoose from 'mongoose'

class Blacklist extends mongoose.Schema {
  constructor() {
    super({
      type: String,
      ip: String,
      details: String,
      reason: String
    })
  }
}

export default mongoose.model('Blacklist', Blacklist)

I see this error in the console.我在控制台中看到此错误。

if (!('pluralization' in schema.options)) schema.options.pluralization = this.options.pluralization;
                                 ^

TypeError: Cannot use 'in' operator to search for 'pluralization' in undefined

I'm not sure why you're attempting to use ES6 classes in this case.我不确定您为什么要在这种情况下尝试使用 ES6 类。 mongoose.Schema is a constructor to create new schemas. mongoose.Schema是创建新模式的构造函数。 When you do当你做

var Blacklist = mongoose.Schema({});

you are creating a new schema using that constructor.您正在使用该构造函数创建一个新模式。 The constructor is designed so that behaves exactly like构造函数的设计使其行为完全像

var Blacklist = new mongoose.Schema({});

What you're alternative,你是另类,

class Blacklist extends mongoose.Schema {

does is create a subclass of the schema class, but you never actually instantiate it anywhere所做的是创建模式类的子类,但您实际上从未在任何地方实例化它

You'd need to do你需要做

export default mongoose.model('Blacklist', new Blacklist());

but I wouldn't really recommend it.但我不会真的推荐它。 There's nothing "more ES6y" about what you are doing.关于你在做什么,没有什么“更多的 ES6y”。 The previous code is perfectly reasonable and is the recommended API for Mongoose.前面的代码非常合理,是Mongoose推荐的API。

Mongoose can natively support es6 classes (since 4.7, and with no transpiler…). Mongoose可以原生支持 es6 类(从 4.7 开始,并且没有转译器……)。

Just write:写吧:

const mongoose = require('mongoose')
const { Model, Schema } = mongoose

const schema = new Schema({
  type: String,
  ip: String,
  details: String,
  reason: String,
})

class Tenant extends Model {}

module.exports = mongoose.model(Tenant, schema, 'tenant');

Why would you want to do it?你为什么要这样做? mongoose.Schema is not expected to be used in this way. mongoose.Schema预计不会以这种方式使用。 It doesn't use inheritance.它不使用继承。

mongoose.Schema is a constructor that takes an object as the first parameter both in ES5 and ES6. mongoose.Schema是一个构造函数,在 ES5 和 ES6 中都将对象作为第一个参数。 No need for ES6 classes here.这里不需要 ES6 类。

Thus even with ES6 the proper way is to have:因此,即使使用 ES6,正确的方法也是:

const Blacklist = mongoose.Schema({
  type: String,
  ip: String,
  details: String,
  reason: String,
});

For those who find this searching around, the original question seems pretty valid to me.对于那些发现这种搜索的人来说,最初的问题对我来说似乎很有效。 I'm using Babel transpiling ES6+ down to 5. My custom mongoose methods did not play well with my async/await code in my calling class.我正在使用 Babel 将 ES6+ 转换为 5。我的自定义 mongoose 方法不能很好地与我的调用类中的异步/等待代码配合使用。 Notably this was null in my instance methods.值得注意的是, this在我的实例方法中为null Using the solution provided here, I was able to arrive at this solution that hopefully helps others searching around.使用此处提供的解决方案,我能够得出这个解决方案,希望能帮助其他人搜索。

import mongoose from 'mongoose'

class Tenant extends mongoose.Schema {
  constructor() {
    const tenant = super({
      pg_id: Number,
      name: String,
      ...
    })

    tenant.methods.getAccountFields = this.getAccountFields
    tenant.methods.getCustomerTypes = this.getCustomerTypes
    tenant.methods.getContactFields = this.getContactFields
    ...
    tenant.methods.getModelFields = this.getModelFields

    return tenant
  }

  getAccountFields() {
    return this.getModelFields(this.account_fields_mapping)
  }

  getCustomerTypes() {
    //code
  }

  getContactFields() {
    //code
  }

  ...

  getModelFields(fields_mapping) {
    //code
  }
}

export default mongoose.model('Tenant', new Tenant)

To do things the ES6, class-like way, as the question states, I simply had to invoke the class with new in the exported mongoose.model function.如问题所述,要以类 ES6 的方式做事,我只需在导出的mongoose.model函数中用new调用类。

export default mongoose.model('Blacklist', new Blacklist)

This might be late to reply still, this may help someone who looking for this.这可能会迟到回复,这可能会帮助寻找这个的人。

With ES6 Classes Schemas have a loadClass() method that you can use to create a Mongoose schema from an ES6 class:对于 ES6 类,模式有一个loadClass()方法,您可以使用该方法从 ES6 类创建 Mongoose 模式:

  • ES6 class methods become Mongoose methods ES6 类方法变成 Mongoose 方法
  • ES6 class statics become Mongoose statics ES6 类静态变量变成 Mongoose 静态变量
  • ES6 getters and setters become Mongoose virtuals ES6 getters 和 setters 成为 Mongoose virtuals

Here's an example of using loadClass() to create a schema from an ES6 class:下面是使用 loadClass() 从 ES6 类创建模式的示例:

class MyClass {
  myMethod() { return 42; }
  static myStatic() { return 42; }
  get myVirtual() { return 42; }
}

const schema = new mongoose.Schema();
schema.loadClass(MyClass);

console.log(schema.methods); // { myMethod: [Function: myMethod] }
console.log(schema.statics); // { myStatic: [Function: myStatic] }
console.log(schema.virtuals); // { myVirtual: VirtualType { ... } }

Reference: this is a sample code from mongoose documentation, for more details mongoose doc参考:这是 mongoose 文档中的示例代码,有关mongoose doc的更多详细信息

I'm going to give a 2022 answer and how I do it with ES6.我将给出 2022 年的答案以及我如何使用 ES6 来实现。 I think that using classes is not bringing benefit while creating a schema since it is just the definition or shape of the data.我认为在创建模式时使用类并没有带来好处,因为它只是数据的定义或形状。

// package.json
{
  ...
  "type": "module",
}
// root/models/users.model.js
import mongoose from 'mongoose'

const userSchema = new mongoose.Schema({ ... })

const UserModel = mongoose.model('Users', userSchema)
export { UserModel }
// root/routes/users.routes.js
import express from 'express'
import { UserModel } from '../models/users.model.js'

const userRouter = express.Router()

userRouter.post('/', async (req, res) => {
  const user = UserModel.create({ ...req.body })
  ...
}

I was having trouble myself using export default and module.exports but export {... } worked as expected.我在使用export defaultmodule.exports时遇到了麻烦,但export {... }按预期工作。

This will work:这将起作用:

import mongoose from 'mongoose';

const { Schema } = mongoose;
const userSchema = new Schema({

  email: {
      type: String,
      required: true
  },
  firstName: {
      type: String,
  },
  lastName: {
      type: String
  },
  age: {
      type: Number
  }
});

export default mongoose.model('User', userSchema);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM