【问题标题】:SailsJS / Waterline ORM : Update multiple entries using only one querySailsJS / Waterline ORM:仅使用一个查询更新多个条目
【发布时间】:2019-04-17 13:10:48
【问题描述】:

我目前正在使用 SailsJS 框架,我正在尝试仅使用我的 MongoDB 数据库中的一个查询来更新一组元素。

这是我正在做的,但记录没有更新..

传入的 JSON:

{
  "cars": [
    {
      "id": "5cb5cbd5c395a01b4c9d86da",
      "latitude": "-5",
      "longitude": "551"
    },
    {
      "id": "5cb5cbd7c395a01b4c9d86db",
      "latitude": "-4",
      "longitude": "4421",
    }
  ]
}

控制器:

async setLocationOfCars(req, res) {

    try {

        sails.log.info(controllerName + "::" + req.options.action + "() - called");

        const carsLocationArray = req.body.cars;

        let response = CarService.setLocationOfCars(carsLocationArray);
        switch (response.status) {
            case constants.RESOURCE_SUCCESSFULLY_UPDATED :
                return HttpResponseService.json(200, res, constants.RESOURCE_SUCCESSFULLY_UPDATED, response.data);
            default:
                return HttpResponseService.internalServerError(res, response);
        }

    } catch(err) {
        return HttpResponseService.internalServerError(res, err);
    }

}

服务:

async setLocationOfCars(cars) {

    try {

        const arrayOfIdsUpdated = [];
        _.forEach(cars, async function(car){

            let attributesToUpdate = {};
            if (car.hasOwnProperty("latitude")) {
                attributesToUpdate.latitude = car.latitude;
            }
            if (car.hasOwnProperty("longitude")) {
                attributesToUpdate.longitude = car.longitude;
            }

            await Car.updateOne({
                id: car.id
            }).set(attributesToUpdate);

            arrayOfIdsUpdated.push(gateway.id)

        });

        return {
            status: constants.RESOURCE_SUCCESSFULLY_UPDATED,
            data  : arrayOfIdsUpdated
        };

    } catch (err) {
        return {
            status : constants.DATABASE_ERROR,
            name   : err.name ? err.name      : "",
            message: err.message ? err.message: "",
            stack  : err.stack ? err.stack    : "",
            code   : err.code ? err.code      : "",
        };
    }

}

【问题讨论】:

    标签: javascript orm sails.js waterline sails-mongo


    【解决方案1】:

    在你的控制器中

    确保您是 awaiting 来自您的服务的响应。

    let response = await CarService.setLocationOfCars(carsLocationArray);
    

    在您的“服务”中

    我可能会将_.forEach 替换为常规的for 循环。在您的情况下,请确保实际定义了 gateway.id 以及您想要返回到调用代码的值(在您的问题中没有对 gateway 的引用)。

    for (let car of cars) {
      let attributesToUpdate = {};
      if (car.hasOwnProperty("latitude")) {
        attributesToUpdate.latitude = car.latitude;
      }
      if (car.hasOwnProperty("longitude")) {
        attributesToUpdate.longitude = car.longitude;
      }
    
      await Car.updateOne({
        id: car.id
      }).set(attributesToUpdate);
    
    
      // Where does gateway.id come from?
      arrayOfIdsUpdated.push(gateway.id)
    }
    

    也就是说,这将执行cars.length 数量的数据库查询,而不是“仅使用一个查询”。

    但为什么不 _.forEach?

    在 forEach 中使用 async 回调看起来不像你希望它做的那样。您的arrayOfIdsUpdated 很可能会在对updateOne 的任何调用运行之前返回到您的控制器代码中。

    以此为例:

    const _ = require('lodash');
    
    function doNothing() {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, 0)
      });
    }
    
    var foos = [1, 2, 3, 4, 5, 6]
    _.forEach(foos, async (foo) => {
      await doNothing();
      console.log(`Finished #${foo}`);
    });
    
    
    console.log('Done!')
    

    运行它会给出输出

    Done!
    Finished #1
    Finished #2
    Finished #3
    Finished #4
    Finished #5
    Finished #6
    

    注意“完成!”在 await 在 forEach 回调中做出响应之前被记录到控制台。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 2015-07-05
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2015-01-13
      相关资源
      最近更新 更多