SailsJS / Waterline ORM:仅使用一个查询更新多个条目
Posted
技术标签:
【中文标题】SailsJS / Waterline ORM:仅使用一个查询更新多个条目【英文标题】:SailsJS / Waterline ORM : Update multiple entries using only one query 【发布时间】: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 : "",
;
【问题讨论】:
【参考方案1】:在你的控制器中
确保您是 await
ing 来自您的服务的响应。
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 回调中做出响应之前被记录到控制台。
【讨论】:
以上是关于SailsJS / Waterline ORM:仅使用一个查询更新多个条目的主要内容,如果未能解决你的问题,请参考以下文章