node.js 具有一对多关系的猫鼬文档引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34985846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongoose document references with a one-to-many relationship
提问by Justin
I'm working on designing a database structure for a new project, and I'm pretty new to MongoDB, and obviously Mongoose.
我正在为一个新项目设计数据库结构,我对 MongoDB 很陌生,显然是 Mongoose。
I've read Mongooses populationdocumentation, where it has a one-to-many relationship, with one Persondocument to many Storydocuments, but the part that confuses me is where instead of the Storydocuments referencing what Persondocument it belongs to, the Personschema has it setup so it has an array of what Storydocuments it 'owns'.
我已经阅读了 Mongooses人口文档,它具有一对多的关系,一个Person文档到多个Story文档,但让我感到困惑的部分是其中的Story文档不是引用Person它所属的文档,而是Person架构设置了它所以它有一个Story它“拥有”的文件的数组。
I'm setting up something very similar to this. But I keep thinking it would be easier when creating new Storydocuments to have the Persondocument ID. But maybe thats just because I'm more familiar with MySQL relationships using joins.
我正在设置与此非常相似的东西。但我一直认为在创建新Story文档时使用Person文档 ID会更容易。但也许那只是因为我更熟悉使用连接的 MySQL 关系。
If this is the best way to do it (and I'm sure it is, since its in the docs), when new Storydocuments are created, whats the best way to update the array of stories in the associated Peopledocument it belongs to? I looked but couldn't find any examples of updating existing documents to add references to other documents (or deleting them for that matter)
如果这是最好的方法(我确定它是,因为它在文档中),那么在Story创建新文档时,更新People它所属的关联文档中的故事数组的最佳方法是什么?我查看了但找不到任何更新现有文档以添加对其他文档的引用的示例(或为此删除它们)
I'm sure this is an easy solution that I just overlooked or something, but any help would be great. Thanks!
我确定这是一个简单的解决方案,我只是忽略了它或其他什么东西,但任何帮助都会很棒。谢谢!
回答by Keiran Tai
Refer to population, here extract an example from Mongoose.
参考人口,这里从猫鼬中提取一个例子。
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Schema.Types.ObjectId,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Schema.Types.ObjectId, ref: 'Person' },
title : String,
fans : [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
var Story = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);
So the example about, Storymodel stores related Person._idin Story._creator. When you find a document of Story, you can use populate()method to define which attribute in Personmodel you want to retrieve at the same time, such as:
所以有关,示例Story相关模型店Person._id在Story._creator。当你找到一个 的文档时Story,你可以使用populate()method来定义Person你想要同时检索模型中的哪个属性,例如:
Story.findOne({_id: 'xxxxxxx'}).populate('person', 'name age').exec(function(err, story) {
console.log('Story title: ', story.title);
console.log('Story creator', story.person.name);
});
I believe this is what you looking for. Or else, you can use nested collectionsinstead.
我相信这就是你要找的。否则,您可以改用嵌套集合。
回答by College Student
The previous answers to this question were helpful, but it may be useful to see more detailed code. The below code is from my Express.js backend for my application. My application allows users to write reviews. When querying the user, I return all of the reviews that the user has made.
之前对这个问题的回答很有帮助,但查看更详细的代码可能会很有用。以下代码来自我的应用程序的 Express.js 后端。我的应用程序允许用户撰写评论。在查询用户时,我返回用户所做的所有评论。
user_model.js
用户模型.js
import mongoose, { Schema } from 'mongoose';
const UserSchema = new Schema({
firstname: String,
lastname: String,
username: { type: String, unique: true },
reviews: [{ type: Schema.Types.ObjectId, ref: 'Review' }],
}, {
toJSON: {
virtuals: true,
},
});
const UserModel = mongoose.model('User', UserSchema);
export default UserModel;
review_model.js
review_model.js
import mongoose, { Schema } from 'mongoose';
const ReviewSchema = new Schema({
body: String,
username: String,
rating: Number,
}, {
toJSON: {
virtuals: true,
},
});
const ReviewModel = mongoose.model('Review', ReviewSchema);
export default ReviewModel;
review_controller.js
review_controller.js
// . . .
export const createReview = (req, res) => {
const review = new Review();
review.username = req.body.username;
review.rating = req.body.rating;
review.body = req.body.body;
review.save()
.then((result) => {
User.findOne({ username: review.username }, (err, user) => {
if (user) {
// The below two lines will add the newly saved review's
// ObjectID to the the User's reviews array field
user.reviews.push(review);
user.save();
res.json({ message: 'Review created!' });
}
});
})
.catch((error) => {
res.status(500).json({ error });
});
};
user_controller.js
用户控制器.js
export const createUser = (req, res) => {
const user = new User();
user.username = req.body.username;
user.email = req.body.email;
user.save()
.then((result) => {
res.json({ message: 'User created!', result });
})
.catch((error) => {
res.status(500).json({ error });
});
};
// . . .
// returns the user object associated with the username if any
// with the reviews field containing an array of review objects
// consisting of the reviews created by the user
export const getUser = (req, res) => {
User.findOne({ username: req.params.username })
.populate('reviews')
.then((result) => {
res.json(result);
})
.catch((error) => {
res.status(500).json({ error });
});
};
回答by Manasov Daniel
As in population docssaid
正如人口文档所说
var aaron = new Person({ _id: 0, name: 'Aaron', age: 100 });
aaron.save(function (err) {
if (err) return handleError(err);
var story1 = new Story({
title: "Once upon a timex.",
_creator: aaron._id // assign the _id from the person
});
story1.save(function (err) {
if (err) return handleError(err);
// thats it!
});
//then add story to person
aaron.stories.push(story1);
aaron.save(callback);
});

