【问题标题】:How to update a nested field in mongodb with monk in node.js如何使用 node.js 中的僧侣更新 mongodb 中的嵌套字段
【发布时间】:2017-10-26 14:47:57
【问题描述】:

我在用新记录更新我的 mongodb 数据库时遇到了一些困难。数据库由数组的练习字段组成,当我执行 PUT 标头时,我想用新记录更新特定练习,而不是覆盖特定练习的整个字段,因为我想保留进度历史.到目前为止,我只能获取 router.get('/:nickname/:info') 中看到的特定嵌套字段,我们可以在其中指定用户及其姓名、年龄或性别。我可以在练习场上做同样的事情,但我一直无法更新这些。这是数据库:

[
{
    "_id": "59283956c52a5420e74966b9",
    "info": {
      "nickname": "annwumy",
      "name": "Bert",
      "gender": "male",
      "age": 25
    },
    "exercises": [
      {
        "exercise": {
          "name": "squats",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "legpresses",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "deadlifts",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "benchpresses",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "pullups",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "shoulderpress",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "curls",
          "records": []
        }
      }
    ]
  },
  {
    "_id": "5928397fc52a5420e74966ba",
    "info": {
      "nickname": "mmsmsy",
      "name": "Mateusz",
      "gender": "male",
      "age": 26
    },
    "exercises": [
      {
        "exercise": {
          "name": "squats",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "legpresses",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "deadlifts",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "benchpresses",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "pullups",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "shoulderpress",
          "records": []
        }
      },
      {
        "exercise": {
          "name": "curls",
          "records": []
        }
      }
    ]
  }
]

这是带有请求的后端代码:

const express = require('express');
const router = express.Router();
const app = express();
const cors = require('cors');
const bodyParser = require('body-parser');
const axios = require('axios');

const monk = require('monk');
const db = require('monk')('localhost/fitness-log');
const users = db.get('users');

app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use('/api/v1', router);


router.get('/listusers', (req, res) => {
  users.find()
    .then(users => res.json(users))
});

router.get('/users/:id', (req, res) => {
  users.find({'_id': req.params.id})
    .then(user => res.json(user[0]))
});

router.get('/:nickname/:info', (req, res) => {
  users.find({'nickname': req.params.nickname}, `info.${req.params.info}`)
    .then(user => res.json(user[0]))
});

router.post('/adduser', (req, res) => {
  users.insert(req.body, (err, result) => {
    res.send(
      (err === null) ? { msg: result } : { msg: err }
    );
  });
});

router.put('/updateinfo/:nickname/:info', (req, res) => {
  const updateQuery = {$set: {}};
  updateQuery.$set[`info.${req.params.info}`] = req.body.value;
  users.update({'nickname': req.params.nickname}, updateQuery, (err, result) => { 
    res.send(
      (err === null) ? { msg: result } : { msg: err }
    );
  });
});

router.put('/addrecord/:nickname/:exercise', (req, res) => {
  const updateQuery = {$push: {}};
  updateQuery.$push[`exercises.${req.params.exercise}`] = req.body;
  users.update({'nickname': req.params.nickname}, updateQuery, (err, result) => { 
    res.send(
      (err === null) ? { msg: result } : { msg: err }
    );
  });
});

router.delete('/deleteuser/:nickname', (req, res) => {
  users.remove({ 'nickname': req.params.nickname }, err => {
    res.send((err === null) ? { msg: '' } : { msg: 'error: ' + err});
  });
});

router.delete('/deleteallusers', (req, res) => {
  users.remove({}, err => {
    res.send(err === null) ? {msg: '' } : { msg: 'error: ' + err};
  });
});

app.listen(3001, () => console.log("Server running at 3001"));

【问题讨论】:

    标签: javascript node.js mongodb multidimensional-array monk


    【解决方案1】:

    错误在更新表达式中:

    {$set: `info.${req.params.info}`}
    

    必须是:

    const updateQuery = {$set: {}};
    updateQuery.$set[`info.${req.params.info}`] = req.params.infoValue;
    users.update({'nickname': req.params.nickname}, updateQuery, (err, result) => { 
    

    【讨论】:

    • 很棒的提示。谢谢。我已经更新了代码,以便它更新特定的练习。当我尝试 PUT 新记录时,它仍然会覆盖练习记录。我希望它将新记录存储在对象数组中的先前记录旁边。不过,您建议的那个可以很好地更新用户名、年龄和性别信息。
    • 您需要更改文档结构。将练习更改为数组,并使用 $push 而不是 $set 插入新练习 - docs.mongodb.com/manual/reference/operator/update/push
    • 你是个魔术师。 :) 非常感谢,我在更新查询中将 $set 更改为 $push 后一切正常。
    • 很高兴帮助你:)
    • 我已经重新创建了数据库模式,以便更容易在前端访问和映射练习,但是现在我再次为更新正确的字段而苦苦挣扎。你知道如何编辑 $push 方法来更新正确的练习.exercise.[specified_name] 记录,即“名称”字段旁边的字段吗?
    猜你喜欢
    • 2014-06-30
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2012-03-25
    • 2011-10-17
    • 1970-01-01
    • 2014-06-01
    相关资源
    最近更新 更多