SailsJS / Waterline ORM:仅使用一个查询更新多个条目

问题描述 投票:0回答:1

我目前正在使用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个回答
1
投票

In your Controller

确保你是awaiting你的服务的回应。

let response = await CarService.setLocationOfCars(carsLocationArray);

In your "Service"

我可能用常规的_.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数量的数据库查询,而不是“仅使用一个查询”。

But why not _.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

注意“完成!”在forEach回调中awaiting响应之前,它会被记录到控制台。

© www.soinside.com 2019 - 2024. All rights reserved.