getting schema attributes from Mongoose Model

后端 未结 9 1813
时光说笑
时光说笑 2020-12-01 06:19

I\'m using Mongoose.js to create models with schemas.

I have a list of models (many) and at times I\'d like to get the attributes/keys that make up a particular mo

相关标签:
9条回答
  • 2020-12-01 06:22

    Yes, it is possible.

    Each schema has a paths property, that looks somewhat like this (this is an example of my code):

    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]
    }
    

    You can access this through an model too. It's under Model.schema.paths.

    0 讨论(0)
  • 2020-12-01 06:27

    You can use Schema.prototype.obj that returns the original object passed to the schema constructor. and you can use it in a utility function to build the object you're going to save.

    import Todo from './todoModel'
    import { validationResult } from 'express-validator'
    
    const buildObject = (body) => {
        const data = {};
        const keys = Object.keys(Todo.schema.obj);
        keys.map(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 })
        }
    }
    

    another way is to to not call the buildObject function and add it in two lines but you will write every key you want to save

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

    Using ES6 shorthand property names

    0 讨论(0)
  • 2020-12-01 06:29

    Just insert the field name you like to get.

    let fieldName = 'birthday'
    console.log(mySchema.schema.paths[fieldName].instance);
    
    0 讨论(0)
  • 2020-12-01 06:30

    Don't have enough rep to comment, but this also spits out a list and loops through all of the schema types.

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

    should print out:

    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
    

    Or you could get all Attributes as an Array like this:

    var props = Object.keys(mySchema.schema.paths);
    
    0 讨论(0)
  • 2020-12-01 06:41

    Solution for lodash, function which picked all schema properties, excluding specified

    _.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
    

    read more here https://gist.github.com/styopdev/95f3fed98ce3ebaedf5c

    0 讨论(0)
  • 2020-12-01 06:41

    In case you want to have all property values (including nested and populated properties), just use toObject() method:

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

    The output would be:

    {
      id: 'someId',
      name: 'someName',
      child: {
        name: 'someChildName'
      }
      ...
    }
    
    0 讨论(0)
提交回复
热议问题