更新Mongoose模式中的动态字段

时间:2017-05-22 13:52:45

标签: node.js mongodb mongoose

我有一个简单的应用程序,它使用NodeJS + Express + MongoDB(mongoose)与API构建进行通信。我的问题被提到了API方面。

我使用此架构在MongoDB中存储用户配置:

{
    user: Number,
        name: String,
        lists: {
            invoices: {
                year: Number,
                orderCol: String,
                order: Number
            }
        }  
    }
}

每个用户只有一个文档,用于存储我的前端应用程序使用的值,以显示按年份排序和筛选的发票列表。

我需要更新文档,但每次只需要更新一个属性。例如,通过调用API,我希望能够将user.lists.invoices.year更改为2017,而无需更改order& orderCol

我向API发送了三个值:列表类型(invoices),要更改的属性(year)和要设置的值(2017)。

// PUT request with this payload
{ 
    list: 'invoices',
    property: 'year',
    value: 2017
}

我正在使用user字段进行查询。

router.put('/lists/:usr', (req, res, next) => {
    var listData = req.body;  // listData.list, listData.property, listData.year
    var usr = req.params.usr;
    Config.findOneAndUpdate(
        { user: usr }, 
        { $set: { ??? } },
        { new: true, upsert: true },
        (err, config) => {
            if (err) return next(err);
            res.json({ data: config });
        }
    )
}) 

请注意可能的重复:我在Google和SO中的搜索总是引导我$运营商,但我不知道这是否是解决方案,无论如何我不知道如何使用在这种情况下。

也许只是我没有设计正确的架构,在这种情况下我会提出任何建议。

1 个答案:

答案 0 :(得分:1)

我对整个API结构不太确定,但我认为我们可以通过以下代码解决这个特定问题:

Config.findOne({ user: usr }, (err, config) => {
  if (err) return next(err);
  // Be careful if config.lists[list] or config.lists[list][property] can be undefined 
  config.lists[list][property] = value;
  // this might be needed
  // config.markModified('lists.' + list + '.' + property);
  config.save(err => {
    if (err) return next(err);
    res.json({ data: config });
  });
});

我们总是可以先找到文档,直接应用一些修改,然后再将其保存到数据库中,而不是使用更新功能。

此外,这种更新API似乎有点不寻常,我无法判断它是否适合你。无论如何,我建议添加一个验证中间件。这样简单的事情可能会有所帮助:

function validator(req, res, next) {

  const fields = ['list', 'property', 'value'];
  if (!fields.every(field => req.body[field] !== undefined)) {
    return res.status(400).json({ error: 1, msg: fields.join(', ') + ' are required' });
  }

  if (['invoices', 'interests', 'etc'].indexOf(req.body.list) === -1) {
    return res.status(400).json({ error: 1, msg: 'list is invalid' });
  }

  // More validations here...

  next();
}

上面的示例不能很好地扩展(可能应该编写一个更通用的验证器中间件以在API之间共享)但希望它仍然可以提供一个有用的想法。