node.js - 更新 Mongoose 模式中的动态字段

标签 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 发送三个值:列表类型 (发票)、要更改的属性 (年份) 和要设置的值 (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 中的搜索总是引导我到 $ 运算符,但我不知道这是否是这个问题的解决方案,无论如何我也不知道在这种情况下如何使用它。

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

最佳答案

我不太确定整个 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 之间共享),但希望它仍然可以提供有用的想法。

关于node.js - 更新 Mongoose 模式中的动态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44114684/

相关文章:

node.js - 科阿的动态路线?

javascript - 如何在不刷新和使用 JQuery/AJAX 的情况下从服务器获取响应?

node.js - 使用 Azure cosmos DB 进行表达

mongodb - 如何在mongodb中找到最小值

mongodb - Mongoose Geo Near Search - 如何在给定距离内排序?

node.js - Azure Web应用程序乏味

node.js - 使用 grunt-mocha-test 创建测试组

javascript - Find() 函数返回未定义 - Mongoose 和 Node.js

node.js - 如何访问 mongoose 中的字段名称 $aggregate->$lookup-> pipeline->$match

arrays - Mongoose 中的唯一数组值