简体   繁体   English

更新所有用户数据Nodejs Rest PUT

[英]Updating all Users Data Nodejs Rest PUT

I am creating a REST Api using Nodejs and Mongo. 我正在使用Nodejs和Mongo创建REST Api。 I am pretty new to Node and I am able to do all others request like GET,POST,DELETE,PUT (for a single user) except Updating all users. 我对Node很陌生,除了更新所有用户外,我还能执行其他所有请求,例如GET,POST,DELETE,PUT(对于单个用户)。

I want to update all users data. 我想更新所有用户数据。 Following is my code. 以下是我的代码。

import mongoose from 'mongoose';
import { Router } from 'express';
import User from '../model/user';
import bodyParser from 'body-parser';

export default({ config, db }) => {
  let api = Router();

  api.put('/', (req, res) => {
    User.find({}, (err, user) => {
      if (err) {
        res.send(err);
      }

      user.name = req.body.name;
      user.salary = req.body.salary;

      user.save(function(err) {
        if (err) {
          res.send(err);
        }
        res.json({ message: 'All User info updated' });
      });
    });
  });

  return api;
}

I am getting user.save is not a function when put request is made. 我收到user.save时发出了放置请求, user.save它不是一个函数。 I went through all the question on this on Stack Overflow, but its very confusing for me. 我在Stack Overflow上经历了所有与此有关的问题,但是这对我来说却很令人困惑。

You can do this. 你可以这样做。 Check Mongoose's document update feature here http://mongoosejs.com/docs/documents.html http://mongoosejs.com/docs/documents.html上检查Mongoose的文档更新功能

import mongoose from 'mongoose';
import {
    Router
} from 'express';
import User from '../model/user';
import bodyParser from 'body-parser';

export default ({
    config,
    db
}) => {
    let api = Router();

    api.put('/', (req, res) => {
        User.update({}, {
            name: req.body.name,
            salary: req.body.salary
        }, {
            multi: true
        }, (err, data) => {
            if (err) {
                res.send(err);
            }
            res.json({
                message: 'All User info updated'
            });
        });
    });

    return api;
}

Problem that you are facing is because of the return type of the find method or I would say query. 您面临的问题是由于find方法的返回类型,或者我会说查询。

find in mongo returns a cursor (something which is a iterator and contains the results of your query) and its implementation in mongoose gives you back an array of documents . 在mongo中的find返回一个cursor (是一个迭代器,包含查询的结果),其在mongoose实现将为您提供一系列文档

So it does not matter if your database has just one users or multiple users, User.find({}) is always going to return you an array (an empty array or an array containing your documents). 因此,无论您的数据库只有一个用户还是多个用户都没有关系, User.find({})总是会返回一个数组(一个空数组或包含您的文档的数组)。 And since the .save() method is available only on valid mongoose models, which an array (result of your query) is not hence you got that error user.save is not a function. 而且由于.save()方法仅在有效的猫鼬模型上可用,因此数组(您的查询结果)不是有效的,因此您会遇到错误user.save is not a function.

Try logging your user that you get after the find query inside callback, you will get an array. 尝试记录您在回调内的find查询之后获得的用户,您将获得一个数组。

Possible Solutions 可能的解决方案

1. Not recommended at all 1.完全不推荐

Iterate over user (I would say users) that you got inside your callback and then inside every iteration call .save() on every user. 遍历用户(我想说用户),使您进入回调,然后在每个用户的每个迭代调用.save()内部。 Keep track of error that may originate while saving a document, and if any error occurs break out of iteration (you may choose to continue as well). 跟踪保存文档时可能产生的错误,如果发生任何错误,请中断迭代(您也可以选择继续)。

Something like this - 像这样-

User.find({}, (err, users) => {
  if (err) {
    res.send(err);
  }

  let errorWhileSaving = null;

  for (let user of users) {

    if (errorWhileSaving) {
      res.send(ererrorWhileSaving);
      break;
    }

    user.name = req.body.name;
    user.salary = req.body.salary;

    user.save(function(err) {
      errorWhileSaving = err;
    });
  }

  res.json({ message: 'All User info updated' });
});

I never recommend this approach because we lose atomicity of our transaction using this one. 我从不推荐这种方法,因为使用这种方法我们失去了交易的原子性。 Any failure while saving any user would result in partial update of database which is really harmful. 保存任何用户时发生的任何故障都将导致数据库的部分更新,这确实是有害的。

Also it issues multiple queries to the database server which definitely affects the performance of a transaction. 它还向数据库服务器发出多个查询,这肯定会影响事务的性能。

By transaction I mean any set of queries(simple or complex) that operates on database. 事务是指对数据库进行操作的任何查询集(简单或复杂)。

2. Recommended 2.推荐

Instead of using .find() then iterating on documents and then saving them by issuing multiple .save() calls, use .update() method . 不要使用.find()然后遍历文档,然后通过发出多个.save()调用来保存它们,而应使用.update()方法

Somewhat like this - 有点像这样-

User.update(
  {}, 
  {
    $set: {
      name: req.body.name,
      salary: req.body.salary
    }
  },
  {
    multi: true
  },
  function (err, results) {
    if (err) {
      res.send(err);
    }

    res.json({ message: 'All User info updated' });
  }
);

Explanation 说明

.update method expects - .update方法期望-

  1. Search criteria - criteria which will be used to find documents to be updated. 搜索条件-将用于查找要更新的文档的条件。 Here we have supplied {} which means that we want to update all documnets inside users collections. 在这里,我们提供了{} ,这意味着我们想更新users集合中的所有documnet。
  2. Update options - These options are mongodb 's update operators. 更新选项-这些选项是mongodb的更新操作符。 Here we are using $set to set two fields on all our documents. 在这里,我们使用$set在所有文档上设置两个字段。
  3. An object representing behaviour of the query. 表示查询行为的对象。 Here we have used {muti: true} which asks mongodb to run this update query on multiple documents that match the search criteria. 在这里,我们使用了{muti: true} ,它要求mongodb在符合搜索条件的多个文档上运行此更新查询。
  4. Callback (optional) - A function that will be called once the query finishes execution, either with error or results. 回调(可选)-查询完成执行后将调用的函数,无论是错误还是结果。

Benefit of using this approach is - 使用这种方法的好处是-

  1. Either all users will get updated or none will. 所有用户都将得到更新,否则将不会。 Atomicity 原子性
  2. Issues single query to database which boosts your query performance. 向数据库发出单个查询,从而提高查询性能。

You can find more info on .update() in mongodb docs. 您可以在mongodb文档中找到有关.update()更多信息。

Points of improvements 改进点

I noted, that you are still using callbacks for handling async tasks. 我注意到,您仍在使用回调来处理异步任务。 If you are not already familiar with promises then go study them and instead of using callback, optimize your code to use Promises. 如果您还不熟悉Promise,则请研究它们,而不是使用回调,而是优化代码以使用Promises。 I have seen good application developers struggling to reason about a code wrapped in callbacks, so be wise and start using Promises for the better future. 我见过优秀的应用程序开发人员在为包装在回调中的代码而苦苦思索,所以要明智并开始使用Promises来创造更好的未来。

Here is a good article to start with Promises. 是一篇很好的文章,从Promises开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM