我正在开发一种功能类似于博客的日记应用程序,即用户可以将标签放在不同的日记条目中。每个“条目”文档都有一个条目引用的标签数组,每个“标签”文档都带有引用它的条目数组:
var entrySchema = new mongoose.Schema({
tags: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Tag"
}
],
body: String,
});
var tagSchema = new mongoose.Schema({
name: String,
entries: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Entry"
}
]
});
创建新条目时,我将遍历“标签”数组,使用新条目ID更新现有标签文档,并为尚不存在的标签文档创建新的标签文档。 然后,我想循环浏览所有条目的标签,并将相应的标签ID推入条目的“标签”引用数组。
Entry.create(entry, function(err, entry) {
if (err) {
console.log(err);
} else {
tags = [tag1,tag2,tagN]; //in reality, this list is sent from a webpage
// now, find all the tags that already exist as documents and push the new entry to their entries arrays
Tag.updateMany(
{ "name": { $in: tags } },
{ $push: { entries: entry } },
function(err, updatedTags) {
if (err) {
console.log(err);
} else {
console.log(updatedTags);
// go through the complete tag list
tags.forEach(function(tag, index) {
Tag.findOne({name: tag}, {_id: 1}, function(err, foundTag) {
if (err) { console.log(err); } else {
// if a tag on the list doesn't exist as a document, create a new document for it
if (!foundTag) {
Tag.create({
name: tag,
user: {
id: req.user._id,
username: req.user.username
},
entries: [entry]
}, function(err, tagGuy) {
if (err) {
console.log(err);
} else {
// save the freshly created tag
tagGuy.save();
}
});
}
}
});
});
// now, every tag in the "tags" array should have a corresponding document.
// I want to take each of those documents and push it into the tags reference array for the new entry
Tag.find({ "name": { $in: tags } }, function(err, foundTags) {
if (err) {
console.log(err);
} else {
console.log("found tags: " + foundTags);
// only prints tag documents that existed before.
foundTags.forEach(function(tag) {
entry.tags.push( tag );
});
entry.save();
}
});
}
}
);
}
});
如代码注释中所述, Tag.find()仅返回在运行此代码之前已经存在的标签,并且返回的标签也未更新。我希望它返回更新的标签以及新创建的标签。为了澄清,更新和创建确实出现在我的数据库中。
如果只是一个标签,我只需在Tag.create()上做一个回调函数,然后将Tag.find()粘贴到那里,但是forEach循环当然会引起问题。
我应该以不同的方式构造代码吗? Tag.find()认为从未发生过整个Tag.updateMany()函数及其所有内容,包括Tag.create()。