将猫鼬文档中的字段设置为数组长度

fug*_*ugu 8 javascript mongoose mongodb node.js

我有一个猫鼬文件:

var SkillSchema = new mongoose.Schema({
    skill: { type: String },
    count: { type: Number, default: 0 },
    associatedUsers: [{ type : mongoose.Schema.Types.ObjectId, ref: 'User' }]
});
Run Code Online (Sandbox Code Playgroud)

我更新如下:

var query = { skill: req.body.skill };
var update = { $addToSet: { associatedUsers: req.params.id } };

var options = { upsert: true, new: true, setDefaultsOnInsert: true };

await skillSchema.findOneAndUpdate(query, update, options);
Run Code Online (Sandbox Code Playgroud)

在此更新过程中,我也想更新count为等于的长度associatedUsers

理想情况下,我希望这可以通过预钩或在更新其他字段的同时进行(即不在后续更新中)findOneAndUpdate

我已经尝试在架构定义之后使用预钩子:

SkillSchema.pre('findOneAndUpdate', async function(){
    console.log("counting associated users");
    this.count = this.associatedUsers.length;
    next();
});
Run Code Online (Sandbox Code Playgroud)

以及在我的UPDATE路由中使用聚合

await skillSchema.aggregate([{ $project: { count: { $size: "$associatedUsers" } } } ])
Run Code Online (Sandbox Code Playgroud)

但是我都不能上班。

有人对我如何实现这一目标有任何建议吗?

use*_*814 5

您可以$set在4.2中像这样使用它在更新中支持聚合管道。

第一个$ set阶段associatedUsers基于先前值和新值来计算a 。$setUnion保持不同的relatedUsers值。

第二个$ set阶段tally根据上一个阶段中的计算结果进行associatedUsers计算。$size计算关联用户值的长度。

var query = {skill: req.body.skill};
var update = [{ $set: { "associatedUsers":{"$setUnion":[{"$ifNull":["$associatedUsers",[]]}, [req.params.id]] }}}, {$set:{tally:{ $size: "$associatedUsers" }}}];
var options = { upsert: true, new: true, setDefaultsOnInsert: true };
await skillSchema.findOneAndUpdate(query, update, options)
Run Code Online (Sandbox Code Playgroud)

如果任何参数解析为null值或引用缺少的字段,则$ setUnion返回null。所以只需要维护我们的运营$ifNull


Joz*_*zeV 2

关于 tally 和 AssociatedUsers.length

// define your schema object
var schemaObj = {
  skill: { type: String },
  associatedUsers: { type: Array }
};

// get the length of users
var lengthOfAsUsers = schemaObj.associatedUsers.length;

// add tally to schema object and set default to the length of users
schemaObj.tally = { type: Number, default: lengthOfAsUsers };

// and pass your schema object to mongoose.Schema
var SkillSchema = new mongoose.Schema(schemaObj);

module.exports = SkillSchema;
Run Code Online (Sandbox Code Playgroud)

编辑您可以随后更新计数,但推荐的解决方案是使用此方法 https://mongoosejs.com/docs/populate.html

const id = "nameSomeId";

SkillSchema.find({ _id: id }).then(resp => {
  const tallyToUpdate = resp.associatedUsers.length;
  SkillSchema.findOneAndUpdate({ _id: id }, { tally: tallyToUpdate }).then(
    resp => {
      console.log(resp);
    }
  );
});
Run Code Online (Sandbox Code Playgroud)