猫鼬填充非规范化数据

时间:2018-07-05 15:16:23

标签: javascript node.js mongodb express mongoose

我有一个User模型和一个Book模型。我希望我的书中的某些数据在每个User文档中进行非规范化处理,但如果需要,还可以选择填充。如果我在ref: 'Book'上设置了books.$._id,它将被填充到_id路径内,这是意外的。我希望人口覆盖非规范化数据。

我该如何完成?

中: users.model.js

const { Schema } = require('mongoose');

const UserSchema = new Schema({
    name: String,
    books: {
        type: [
            {
                _id: Schema.Types.ObjectId,
                title: String,
                length: Number,
            },
        ],
        default: [],
    },
});

所需结果

中: users.controller.js

app.get('/', async (req, res, next) => {
    const users = await User.find({})
    /*
    users: [{
        _id: ObjectId(),
        name: 'Andrew',
        books: [{
            _id: ObjectId(),
            title: 'Game of Thrones',
            length: 298,
        }, { ... }],
    }, { ... }]
    */
});

app.get('/:id', async (req, res, next) => {
    const book_id = req.params.id;
    const user = await User.findById(book_id).populate({
        path: 'books',
        model: 'Book',
    });
    /*
    user: {
        _id: ObjectId(),
        name: 'Andrew',
        books: [{
            _id: ObjectId(),
            name: 'Game of Thrones',
            length: 298,
            author: 'Simone Dunow',
            releasedOn: Date(),
            price: 30,
            ...
        }, { ... }],
    }
    */
});

到目前为止我尝试过的模式:

    books: {
        type: [
            {
                _id: Schema.Types.ObjectId,
                title: String,
                length: Number,
            },
        ],
        default: [],
        ref: 'Book',
    },

返回{ _id: null }

的数组
    books: {
        type: [
            {
                _id: {
                    type: Schema.Types.ObjectId,
                    ref: 'Book',
                },
                title: String,
                length: Number,
            },
        ],
        default: [],
    },

书被填充在_id内:{ _id: { Book } }

    books: {
        type: [
            {
                type: {
                    _id: Schema.Types.ObjectId,
                    title: String,
                    length: Number,
                },
                ref: 'Book',
            },
        ],
        default: [],
    },

引发异常:类型无效

2 个答案:

答案 0 :(得分:0)

const UserSchema = new Schema({
    name: String,
    books: [{
        id: { type : Schema.Types.ObjectId, ref : 'Book'} //Whatever string you have used while modeling your schema
        title: String,
        length: Number,
    }],
});

使用模式时,您可以按以下步骤进行填充:

populate({ path: 'books.id' })

输出:

{ 
    _id : // someid
    name : "somename"
    books : [
        { 
          id : {//document referring to Books collection},
          title : "sometitle",
          length : //somelength
        }, ...
    ]
}

答案 1 :(得分:0)

对于可能仍希望实现完全替代,完全公开的任何人:对于某些传教士来说,这可能有点麻烦,甚至在高流量应用程序上可能会造成性能损失,但是如果您确实想做到这一点,则可以点击如下所示的模式的toJSON方法:

UserSchema.method('toJSON', function () {
  let obj = this.toObject();
  obj.books = obj.books.map(
    (book) => (Schema.Types.ObjectId.isValid(book.id)) ? book : book.id
  );
  return obj;
});

这里发生的基本上是,当book.id被填充时,我们将整个属性替换为填充的结果,否则我们将通过检查书籍的id的有效性来返回原始对象(填充时将是完整的绽放的对象而不是ID)。