SailsJS / Waterline ORM:仅使用一个查询更新多个条目
SailsJS / Waterline ORM : Update multiple entries using only one query
我目前正在使用 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 : "",
};
}
}
在你的控制器中
确保您await
正在接收服务的响应。
let response = await CarService.setLocationOfCars(carsLocationArray);
在你的"Service"
我可能会将 _.forEach
替换为常规 for
循环。在您的情况下,如下所示,确保实际定义了 gateway.id
以及您想要 return 调用代码的值(您的问题中没有对 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
次数据库查询,而不是 "using only one query"。
但为什么不 _.forEach?
在 forEach 中使用 async
回调之类的方法看起来不会执行您可能希望它执行的操作。在 对 updateOne
运行 的任何调用之前,您的 arrayOfIdsUpdated
很可能会被 return 编辑为空的控制器代码。
以此为例:
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
请注意 "Done!" 如何在 await
在 forEach 回调中进行响应之前记录到控制台。
我目前正在使用 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 : "",
};
}
}
在你的控制器中
确保您await
正在接收服务的响应。
let response = await CarService.setLocationOfCars(carsLocationArray);
在你的"Service"
我可能会将 _.forEach
替换为常规 for
循环。在您的情况下,如下所示,确保实际定义了 gateway.id
以及您想要 return 调用代码的值(您的问题中没有对 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
次数据库查询,而不是 "using only one query"。
但为什么不 _.forEach?
在 forEach 中使用 async
回调之类的方法看起来不会执行您可能希望它执行的操作。在 对 updateOne
运行 的任何调用之前,您的 arrayOfIdsUpdated
很可能会被 return 编辑为空的控制器代码。
以此为例:
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
请注意 "Done!" 如何在 await
在 forEach 回调中进行响应之前记录到控制台。