我有一个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: [],
},
引发异常:类型无效
答案 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)。