Node.js mongoose:在X集合中创建新元素,在Y集合中更新另一个元素
我正在尝试开发一个CRUD应用程序,供用户存储、添加、删除和更新食谱。它建立在MEVN堆栈上。由于我需要向用户展示他们创建的配方,因此我尝试基于此模型创建一个配方:Node.js mongoose:在X集合中创建新元素,在Y集合中更新另一个元素,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在尝试开发一个CRUD应用程序,供用户存储、添加、删除和更新食谱。它建立在MEVN堆栈上。由于我需要向用户展示他们创建的配方,因此我尝试基于此模型创建一个配方: const RecipeSchema = new Schema({ title: { type: String, required: [true, 'Title of the recipe is required'], }, category: { type:
const RecipeSchema = new Schema({
title: {
type: String,
required: [true, 'Title of the recipe is required'],
},
category: {
type: Array,
required: [true, 'Category is required'],
},
description: {
type: String,
required: [true, 'Description is required'],
},
imgUrl: {
type: String,
required: [true, 'Image is required'],
},
ingredients: {
type: Array,
required: [true, 'Ingredients are required'],
},
timeOfPreparation: {
type: String,
required: true,
},
preparation: {
type: String,
required: true,
},
sourceName: {
type: String,
required: true,
},
sourceUrl: {
type: String,
required: true,
},
author: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
});
const Recipe = mongoose.model('Recipe', RecipeSchema);
module.exports = Recipe;
同时更新用户模型,基于此:
const UserSchema = Schema({
googleId: String,
name: String,
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Recipe' }],
authoredRecipes: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Recipe' }],
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
在控制器中,我有以下方法(根据@Stock Overlaw注释):
})
在转到/创建端点时调用此方法。然而,即使我得到了所有正确的id(req.body.author和recipe.id),我也无法让它工作。在我的mLab配方集合中,配方显示正确(我使用authorId插入的所有数据),但是在用户集合中,authoredRecipes数组保持为空
如何让mongoose既在一个集合中创建一个对象,又根据其id更新另一个对象?forfindbyiandupdate
需要\u id
字段作为其值,而不是对象:
User.findByIdAndUpdate(req.body.author, {
$push: { authoredRecipes: recipe.id }
});
// equivalent to the more general method:
User.findOneAndUpdate({ _id: req.body.author }, {
$push: { authoredRecipes: recipe.id }
});
// and if you don't need the modified document in your callback, this should be faster:
// EDIT: this is advised against (we should use a user object, not the collection)
User.update({ _id: req.body.author }, { // or updateOne
$push: { authoredRecipes: recipe.id }
});
编辑:一个有效的、最少的示例
介意{new:true}
也许吧?取决于你如何测试它是否有效
const mongoose = require('mongoose');
const fs = require('fs');
const userIdFile = './tmp.txt'; // just for this test
mongoose.connect('mongodb://localhost/meuh', {
useNewUrlParser: true, // removes a deprecation warning
useFindAndModify: false // removes another deprecation warning
});
// make schemas/models
const RecipeSchema = mongoose.Schema({
title: { type: mongoose.Schema.Types.String }
});
const UserSchema = mongoose.Schema({
name: { type: mongoose.Schema.Types.String },
data: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Recipe' }]
});
const RecipeModel = mongoose.model('Recipe', RecipeSchema);
const UserModel = mongoose.model('User', UserSchema);
// user precreation
// UserModel.create({
// name: 'me, myself and I'
// }).then((user) => {
// fs.writeFile(userIdFile, user.id, console.log.bind(null, 'error writing file:'));
// mongoose.connection.close();
// });
// return;
// fetch user
const userId = fs.readFileSync(userIdFile);
let pushedRecipeId; // to test everything went smooth
RecipeModel.create({
title: 'pasta solo'
}).then((recipe) => {
console.log('created recipe:', recipe);
pushedRecipeId = recipe.id;
return UserModel.findOneAndUpdate(
{ _id: userId },
{ $push: { data: recipe.id } },
{ new: true } // forces callback to be passed a fresh object
);
}).then((user) => {
console.log('updated user:', user);
console.log('izok:', !!~user.data.indexOf(pushedRecipeId));
mongoose.connection.close();
}).catch((err) => {
console.log('error', err);
mongoose.connection.close();
})
我得到的示例输出:
#创建用户(未注释此部分)
ubuntu@ubuntu-VirtualBox:~/web/test$节点。
写入文件时出错:null
#调用$push(重新评论用户创建)
ubuntu@ubuntu-VirtualBox:~/web/test$节点。
创建的配方:{uu id:5c72be7032bd2f1acad37c95,标题:“意大利面独奏”,uuu v:0}
更新的用户:{数据:[5c72be7032bd2f1acad37c95],
_id:5c72be6a8143fd1aa9416d85,
名字:“我,我自己和我”,
__v:0}
伊佐克:是的
#再推一次$push
ubuntu@ubuntu-VirtualBox:~/web/test$节点。
创建的配方:{id:5c72c020c2ac7a1b8c65fa36,标题:'意大利面独奏',{v:0}
更新用户:{数据:[5c72be7032bd2f1acad37c95,5c72c020c2ac7a1b8c65fa36],
_id:5c72be6a8143fd1aa9416d85,
名字:“我,我自己和我”,
__v:0}
伊佐克:是的
#再三
ubuntu@ubuntu-VirtualBox:~/web/test$节点。
创建的菜谱:{id:5c72c023bf62331b97ef096b,标题:'意大利面独奏',{v:0}
更新的用户:{数据:
[5c72be7032bd2f1acad37c95,
5c72c020c2ac7a1b8c65fa36,
5c72c023bf62331b97ef096b],
_id:5c72be6a8143fd1aa9416d85,
名字:“我,我自己和我”,
__v:0}
伊佐克:是的
#结束
ubuntu@ubuntu-VirtualBox:~/web/test$
我看不出你的代码有什么问题,但至少你有一些东西可以比较。。。希望这有帮助 不幸的是,这并不能解决这个问题,我仍然没有收到任何来自authoredRecipes的回复array@llievredemars我更新了一个例子,希望你能找出问题所在。谢谢!我插入了{new:true},这就解决了这个问题!我很感激你花时间调试这个:)祝你有一个很棒的一天!好东西!但这意味着您没有完全测试数组是否为空:在回调中它只是空的(实际上:每次都晚了一步),而DB已经存储了它
const mongoose = require('mongoose');
const fs = require('fs');
const userIdFile = './tmp.txt'; // just for this test
mongoose.connect('mongodb://localhost/meuh', {
useNewUrlParser: true, // removes a deprecation warning
useFindAndModify: false // removes another deprecation warning
});
// make schemas/models
const RecipeSchema = mongoose.Schema({
title: { type: mongoose.Schema.Types.String }
});
const UserSchema = mongoose.Schema({
name: { type: mongoose.Schema.Types.String },
data: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Recipe' }]
});
const RecipeModel = mongoose.model('Recipe', RecipeSchema);
const UserModel = mongoose.model('User', UserSchema);
// user precreation
// UserModel.create({
// name: 'me, myself and I'
// }).then((user) => {
// fs.writeFile(userIdFile, user.id, console.log.bind(null, 'error writing file:'));
// mongoose.connection.close();
// });
// return;
// fetch user
const userId = fs.readFileSync(userIdFile);
let pushedRecipeId; // to test everything went smooth
RecipeModel.create({
title: 'pasta solo'
}).then((recipe) => {
console.log('created recipe:', recipe);
pushedRecipeId = recipe.id;
return UserModel.findOneAndUpdate(
{ _id: userId },
{ $push: { data: recipe.id } },
{ new: true } // forces callback to be passed a fresh object
);
}).then((user) => {
console.log('updated user:', user);
console.log('izok:', !!~user.data.indexOf(pushedRecipeId));
mongoose.connection.close();
}).catch((err) => {
console.log('error', err);
mongoose.connection.close();
})