编辑数组中对象的值

时间:2018-03-01 23:32:32

标签: javascript node.js mongodb express mongoose

我有这个对象:

{
  "_id" : ObjectId("5a8d83d5d5048f1c9ae877a8"),
  "websites" : [
          "",
          "",
          ""
  ],
  "keys" : [
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877af"),
                  "name" : "Google",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877ae"),
                  "name" : "Built With",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877ad"),
                  "name" : "Check Host",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877ac"),
                  "name" : "Alexa",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877ab"),
                  "name" : "Facebook",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877aa"),
                  "name" : "Instagram",
                  "value" : ""
          },
          {
                  "_id" : ObjectId("5a8d83d5d5048f1c9ae877a9"),
                  "name" : "Moz",
                  "value" : ""
          }
  ],
  "username" : "admin@admin",
  "isPremium" : false,
  "accType" : "admin",
  "hash" : "very long hash",
  "salt" : "long salt",
}

现在。使用NodeExpress和Mongoose我需要能够编辑value数组中每个对象内的keys字段。

我的GET操作就是:

// GET: /websites/:_id - show edit form
router.get('/keys/edit/:_id', isAdmin, function(req, res, next) {
  // console.log('tada');
  // console.log(req.params._id);

  Account.findOne({ _id: req.user._id }, function(err, user) {
    var selectedKey = findById(user.keys, req.params._id);
    // var keys = user.keys.findOne(req.params._id);
    console.log(selectedKey);
    res.render('admin/edit', {
      title: 'Edit websites',
      user: req.user,
      value: selectedKey.value,
    });
  });
});

应用程序的工作原理是:管理员登录。他看到所有用户并选择他想要修改的用户,然后管理员查看所有密钥。我将附上截图以更清楚地解释它。

enter image description here

enter image description here

enter image description here

现在。我想我知道自己需要做什么,但我不知道如何将其翻译成代码。

我认为我需要:找到数组元素的索引,就像在GET请求中一样,用发布的值更新值。我想我需要在数组中找到索引。

但正如我所说,我不知道该怎么做。

我的POST现在看起来像这样:

// POST: /keys/edit/_id - save updates
router.post('/keys/edit/:_id', isAdmin, function(req, res, next) {
  var p = req.params;
  var b = req.body;
  Account.findOne({ _id: req.user._id }, function(err, user) {
    var selectedKey = findById(user.keys, req.params._id);
    // console.log('Key value: ' + req.body.keyValue);
    // console.log('Selected key: ' + selectedKey);
    console.log('id:' + req.params._id);
    if (err) {
      console.log(err);
    } else {
      console.log(user);
      user.keys.set(req.params._id, req.body.keyValue);
      user.save(err => {
        if (err) {
          console.log(err);
        } else {
          console.log('all good');
        }
        res.redirect('/admin');
      });
    }
  });
编辑:所以我现在正在研究它一段时间,我想出了这个。我正在使用正确的用户,我正在抓取内部的键数组,但我不知道如何在数组中找到对象的id,我需要编辑哪个(对象)。

有很多嵌套,这可能会导致一些问题。

编辑2:我正在攻击我的帐户模型。早点忘了。遗憾。

var mongoose = require('mongoose');

var website = require('./website');

var plm = require('passport-local-mongoose');

    var accountSchema = new mongoose.Schema({
      isPremium: Boolean,
      accType: String,
      websites: [],
      keys: [
        { name: String, value: String },
        { name: String, value: String },
        { name: String, value: String },
        { name: String, value: String },
        { name: String, value: String },
        { name: String, value: String },
        { name: String, value: String },
      ],
    });

accountSchema.plugin(plm);

module.exports = mongoose.model('Account', accountSchema);

2 个答案:

答案 0 :(得分:1)

您可以使用$positional运算符以原子方式执行更新。

您包含_id中的字段(keys)以找到元素的索引,并将更新部分中查询部分中找到的索引替换为占位符($)在value中设置keys

 router.post('/keys/edit/:_id', isAdmin, function(req, res, next) {
  var p = req.params;
  var b = req.body;
  Account.findOneAndUpdate(
   {_id: req.user._id,'keys._id':req.params._id }, 
   {$set:{'keys.$.value':req.body.keyValue}},
   {new: true}, 
   function(err, account) {}
);

答案 1 :(得分:0)

这个问题对我来说并不完全清楚你要做什么,但我可以推断出你想要做的事情是:

您的某个对象的Array keys具有以下形状:

{
    "_id" : ObjectId("5a8d83d5d5048f1c9ae877af"),
    "name" : "Google",
    "value" : ""
}

从您的示例对象判断,我推断架构的定义类似于:

const mongoose = require('mongoose')

const definition = {
  websites: [String],
  keys: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Key'
  }]
}

const accountSchema = new mongoose.Schema(definition)

module.exports = mongoose.model('Account', topicSchema)

通过路径的外观,您希望在给定索引处更新/编辑该对象:keys[i]。如果是这种情况,则无需手动遍历阵列,直接更新模型:

const Key = require('./path/to/models/Key')

router.post('/keys/edit/:id', async (req, res) => {
    const { keyValue } = req.body
    const conditions = { _id: req.params.id }
    await Key.findOneAndUpdate({ id }, { value: keyValue }).exec()
    res.status(201).json()
})

查询父模型时,将更新数组中的项目。