【问题标题】:getting schema attributes from Mongoose Model从 Mongoose 模型中获取模式属性
【发布时间】:2013-06-06 18:47:03
【问题描述】:

我正在使用 Mongoose.js 创建带有模式的模型。

我有一个模型列表(很多),有时我想获取构成特定模型的属性/键。

有没有一种方法可以提取任何给定模型的属性模式?

例如,

var mySchema = module.exports = new Schema({
  SID: {
    type: Schema.Types.ObjectId
    //, required: true
  },
  teams: {
    type: [String]
  },
  hats: [{
    val: String,
    dt: Date
  }],
  shields: [{
    val: String,
    dt: Date
  }],
  shoes: [{
    val: String,
    dt: Date
  }]
}

);

是否可以提取/识别架构[SID, hats, teams, shields, shoes]的属性??

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    您可以使用 Schema.prototype.obj 来返回传递给架构构造函数的原始对象。您可以在实用程序函数中使用它来构建您要保存的对象。

    import Todo from './todoModel'
    import { validationResult } from 'express-validator'
    
    const buildObject = (body) => {
        const data = {};
        const keys = Object.keys(Todo.schema.obj);
        keys.forEach(key => { if (body.hasOwnProperty(key)) data[key] = body[key] })
        return data;
    }
    
    const create = async (req, res) => {
        try {
            const errors = validationResult(req);
            if (!errors.isEmpty()) return res.json(errors);
            let toBeSaved = buildObject(req.body);
            const todo = new Todo(toBeSaved);
            const savedTodo = await todo.save();
            if (savedTodo) return res.json(savedTodo);
            return res.json({ 'sanitized': keys })
        } catch (error) {
            res.json({ error })
        }
    }
    

    另一种方法是不调用 buildObject 函数并将其添加到两行中,但您将编写要保存的每个键

    let { title, description } = req.body;
    let toBeSaved = { title, description };
    

    使用 ES6 简写属性名

    【讨论】:

      【解决方案2】:

      我的解决方案使用猫鼬模型。

      架构属性

      const schema = {
        email: {
          type: String,
          required: 'email is required',
        },
        password: {
          type: String,
          required: 'password is required',
        },
      };
      

      架构

      const FooSchema = new Schema(schema);
      

      型号

      const FooModel = model('Foo', FooSchema);
      

      从模型中获取属性:

      Object.keys(FooModel.schema.tree)
      

      结果:

      [
        'email',
        'password',
        '_id',
        '__v'
      ] 
      

      【讨论】:

        【解决方案3】:

        接受的答案对我不起作用。 但是使用 Mongoose 5.4.2 我可以通过执行以下操作来获取密钥:

        const mySchema = new Schema({ ... });
        
        const arrayOfKeys = Object.keys(mySchema.obj);
        

        不过,我正在使用 typescript。这可能是问题所在。

        【讨论】:

          【解决方案4】:

          只需插入您想要获取的字段名称即可。

          let fieldName = 'birthday'
          console.log(mySchema.schema.paths[fieldName].instance);
          

          【讨论】:

            【解决方案5】:

            如果您想拥有所有属性值(包括嵌套和填充属性),只需使用toObject() 方法:

            let modelAttributes = null;
            SomeModel.findById('someId').populate('child.name').exec().then((result) => {
              modelAttributes = result.toObject();
              console.log(modelAttributes);
            });
            

            输出将是:

            {
              id: 'someId',
              name: 'someName',
              child: {
                name: 'someChildName'
              }
              ...
            }
            

            【讨论】:

              【解决方案6】:

              如果您只想拥有您添加的属性,而不是 ORM 以“$___”开头的添加方法,则必须将文档转换为对象,然后像这样访问属性:

              Object.keys(document.toObject());
              

              【讨论】:

                【解决方案7】:

                lodash 的解决方案,选择所有模式属性的函数,不包括指定的

                _.mixin({ pickSchema: function (model, excluded) {
                    var fields = [];
                    model.schema.eachPath(function (path) {
                       _.isArray(excluded) ? excluded.indexOf(path) < 0 ? fields.push(path) : false : path === excluded ? false : fields.push(path);
                    });
                    return fields;
                   }
                });
                
                _.pickSchema(User, '_id'); // will return all fields except _id
                
                _.pick(req.body, _.pickSchema(User, ['_id', 'createdAt', 'hidden'])) // all except specified properties
                

                在此处阅读更多信息https://gist.github.com/styopdev/95f3fed98ce3ebaedf5c

                【讨论】:

                  【解决方案8】:

                  没有足够的代表发表评论,但这也会产生一个列表并循环遍历所有架构类型。

                  mySchema.schema.eachPath(function(path) {
                      console.log(path);
                  });
                  

                  应该打印出来:

                  number
                  name.first
                  name.last
                  ssn
                  birthday
                  job.company
                  job.position
                  address.city
                  address.state
                  address.country
                  address.street
                  address.number
                  address.zip
                  email
                  phones
                  tags
                  createdBy
                  createdAt
                  updatedBy
                  updatedAt
                  meta
                  _id
                  __v
                  

                  或者您可以像这样将所有属性作为数组获取:

                  var props = Object.keys(mySchema.schema.paths);
                  

                  【讨论】:

                  • 这不好,因为它会给你对象的所有属性,包括方法!
                  • @e-nouri 这不是我得到的行为(至少在 v4 中)。 schema.eachPath( ) 结果中不包含方法和静态数据
                  【解决方案9】:

                  是的,有可能。

                  每个架构都有一个paths 属性,看起来有点像这样(这是我的代码示例):

                  paths: {
                      number: [Object],
                      'name.first': [Object],
                      'name.last': [Object],
                      ssn: [Object],
                      birthday: [Object],
                      'job.company': [Object],
                      'job.position': [Object],
                      'address.city': [Object],
                      'address.state': [Object],
                      'address.country': [Object],
                      'address.street': [Object],
                      'address.number': [Object],
                      'address.zip': [Object],
                      email: [Object],
                      phones: [Object],
                      tags: [Object],
                      createdBy: [Object],
                      createdAt: [Object],
                      updatedBy: [Object],
                      updatedAt: [Object],
                      meta: [Object],
                      _id: [Object],
                      __v: [Object]
                  }
                  

                  您也可以通过模型访问它。它在Model.schema.paths 下。

                  【讨论】:

                  • 你能提供资源吗?
                  • 我不明白。你想要链接吗?
                  • 当然...只是我以后可以参考的东西,而不是在这里提问。
                  • 如果您不知道架构,有没有办法从数据库对象中获取?
                  • 也许可以尝试使用modelNames() 遍历已注册的模型,然后以相同的方式检索模型及其路径。
                  猜你喜欢
                  • 2019-02-27
                  • 2014-12-10
                  • 2015-05-03
                  • 2023-02-02
                  • 1970-01-01
                  • 2015-08-23
                  • 1970-01-01
                  • 2014-03-30
                  相关资源
                  最近更新 更多