У меня есть следующий код. Используя $ geoNear, я нахожу ближайшую транзитную остановку к заданной координате gps. Как некоторые из вас могут знать, $ geoNear возвращает только местоположение (loc) ближайшей точки. Чтобы получить информацию о ближайшей остановке, я запрашиваю коллекцию STOPS с использованием местоположения.Mongo возвращает undefined, но данные есть
Проблема в том, что она беспорядочно возвращает неопределенные. Когда я запрашиваю стопы из оболочки mongo, используя параметры agency_key и и loc, я подтверждаю, что данные есть. Я подозреваю, что эта проблема может быть вызвана асинхронностью, но я не могу понять, почему. Я попытался упростить свой вопрос до 'вызов async-функции в forEach loop', но у меня пока нет ничего.
Почему он не возвращается?
...
TmStop.aggregate([{
$geoNear: {
near: [lon, lat],
maxDistance: radiusInDegrees,
includeLocs: "distance.location",
distanceField: "distance.calculated",
query: {
agency_key: {
$in: agencyKeys
}
}
}
}, {
$project: {
route_id: 1,
route_type: 1,
direction_id: 1,
"distance.calculated": 1,
"distance.location": 1
}
}])
.exec(function(e, results) {
if (e) {
console.log('e->', e.errmsg);
var res = "Something went wrong with the database: " + e;
cb(e, res);
} else if (!e) {
if (results.length) {
console.log('results->', results.length);
var i = 0;
results.forEach(function(result, index) {
console.log(index, result);
Stop.find({
agency_key: {
$in: agencyKeys
},
loc: result.distance.location
})
.exec(function(e, stop) {
if (e) {
throw new Error('Error getting stop due to:' + e);
}
var obj = {};
obj.route_id = result.route_id;
obj.route_type = result.route_type;
obj.direction_id = result.direction_id;
obj.distance = result.distance.calculated;
obj.locationUsed = result.distance.location;
// console.log('### ', index, ' ####');
// console.log('@Stop.find agencyKeys-> ', agencyKeys);
// console.log('@Stop.find loc->', result.distance.location);
// console.log(stop[0]);
obj.stop = stop[0];
objArr.push(obj);
i++;
if (i === results.length) {
cb(e, objArr);
}
});
}); //end of forEach
} else {
cb(e, []);
}
}
});
Большое спасибо за этот подробный ответ. Я не знал, что агрегированные функции возвращают простой объект, в отличие от документов мангуста. Это очень ценная информация. Я знаком с асинхронной библиотекой. Я хотел попробовать написать эту часть без асинхронной библиотеки, но ясно, что этот подход не очень хорошо работает для меня. Еще раз спасибо. – melis
@melis Вы «могли» сделать что-то подобное с обещаниями вместо этого (в основном «Promise.all (array_of_queries)»), но часть «limit» (что в большинстве случаев является хорошей идеей) займет немного «ручного проката» "реализовать. Если вы на самом деле не готовы писать много своих собственных слоев библиотеки для таких вещей, обычно это меньшее зло, чтобы просто включить другую зависимость для того, что уже обрабатывает ее. –