javascript - Mongoose - How to initialize a default field value on update bulkOp
问题描述
Problem:
Cannot work aggregation in non-existent field.I have Follow Schema
which contains the following fields:
_user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
following: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
default: []
}],
followers: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
default: []
}],
And when a user follows someone, I have this:
const bulk = Follow.collection.initializeUnorderedBulkOp();
bulk.find({ _user_id: req.user._id }).upsert().updateOne({
$addToSet: {
following: Types.ObjectId(follow_id)
}
});
bulk.find({ _user_id: Types.ObjectId(follow_id) }).upsert().updateOne({
$addToSet: {
followers: req.user._id
}
});
bulk.execute((err, doc) => {
...
})
And when this successfully executes, it will be saved in MongoDB.
Now the problem is when the data is just being saved for the first time, the bulk
op above
only saves the $addToSet
field specified.
For example, when I run this:
bulk.find({ _user_id: Types.ObjectId(follow_id) }).upsert().updateOne({
$addToSet: {
followers: req.user._id
}
});
And this will yield to:
{
_id: ObjectId(544987dfgsld3),
followers: [ ObjectId(34578778g6d8f7g6) ] // followers gets saved
// But how do I initialize the following as empty array?
}
And now I get error in my aggregation because the field is not existent
const result = await Follow.aggregate([
{
$match: { _user_id: user._id }
},
{
$project: {
_id: 0,
followingCount: { $size: '$following' }, // I get Error here $size field must be array but it doesnt exist
followersCount: { $size: '$followers' },
followers: 1
}
},
]);
解决方案
Solved it by checking for non-existent field in my bulkOp query:
bulk
.find({
_user_id: Types.ObjectId(follow_id),
following: { // added this block
$exists: false
}
})
.upsert()
.updateOne({
$set: { // and use $set operator
following: []
}
});
And a much simpler version using aggregate:
{
$project: {
following: { $ifNull: ["$following", []] }, // SET DEFAULTS IF NULL OR NON_EXISTENT
followers: { $ifNull: ["$following", []] },
followers: 1
}
},
{
$project: {
_id: 0,
followingCount: { $size: '$following' },
followersCount: { $size: '$followers' },
followers: 1
}
},
More info about $ifNull Operator
推荐阅读
- python - R和jupyter notebook安装问题
- javascript - D3.js 用对象数据渲染条形图的问题
- javascript - Bootstrap popper.js 未能在资源的“完整性”属性中找到有效的摘要
- string - 拆分字符串重复 Tcl
- sql - 如何使用sql在父母中获取孩子的孩子值
- julia - Julia - 控制台的行为不同于 include("myfile.jl")
- graphql - 如何处理 GraphQL 模式中的空值
- python - PyCharm:无法安装 opencv-contrib-python
- javascript - 设置所选单选按钮的背景颜色
- excel - 基于在另一个表中查找代码和值的 Excel 总和