В моей базе данных три коллекции, вызовы, пользователи и записи.У соревнований есть поля, такие как заголовок, описание и идентификатор соревнования.Записи представляют собой завершенные задачи и содержат поля, такие как идентификатор пользователя, идентификатор задачи и изображение.Я хочу объединить данные в коллекции записей с соответствующей задачей, чтобы у меня был документ, содержащий заголовок, описание, идентификатор задачи и изображение.Я пытаюсь запросить коллекцию запросов на основе массива идентификаторов, полученных из коллекции записей, а затем добавляю результат запроса записи в качестве нового поля в документ.Я реализовал цикл for, который позволяет мне каждый раз запрашивать другой идентификатор.Я хотел бы добавить результат запроса в массив, но иногда он пропускает результаты, и только некоторые из запросов присутствуют в результирующем массиве.Например, когда я отправляю вызов API в первый раз, сервер возвращает 2 JSON-объекта в массиве, но в следующий раз он возвращает только один.Я думаю, что что-то не так с синхронизацией цикла for и запросов.Как я могу заставить его возвращать правильные документы каждый раз?Кроме того, есть ли лучший способ объединить две коллекции без цикла for?
Я пробовал множество различных способов завершить цикл for, не пропуская ни одного запроса или возвращая готовый массив слишком рано, но не смог этого сделать.Эта текущая реализация работает при первом вызове API, но при следующем не работает.Я использую MongoDB (и стек MERN), и у меня есть REST API, куда я отправляю вызовы из моего интерфейса React.
exports.getDoneChallenges = [check("userId").isLength({ min: 24 }),
function(req, res) {
var myPromise = () =>
new Promise((resolve, reject) => {
// Find all challenges the user has completed.
Entry.find({ userId: req.params.id }, { _id: 0 })
.sort({ challengeId: -1 })
.exec()
.then(result => {
// Check if the user hasn't completed any challenges.
if (!result) {
console.log("Zero completed challenges.");
res
.status(401)
.json({ message: "No completed challenges found." });
} else {
// Save the completed challenge's identifiers in an array.
var ids = new Array();
for (var i = 0; i < result.length; i++) {
// Cast identifiers to ObjectID
ids.push(ObjectID(result[i].challengeId));
}
// Array of completed challenges + images relating to each.
var challenge_arr = new Array();
for (let i = 0; i < result.length; i++) {
// Match the corresponding challenge id's from entries to
challenges and add image as a new field.
Challenge.aggregate([
{ $match: { challengeId: ids[i] } },
{ $addFields: { image: result[i] } }
])
.exec()
.then(challenge => {
/* Create a new object, which has the needed fields for
the response.*/
var challenge_obj = new Object();
challenge_obj.title = challenge[0].title;
challenge_obj.challengeId = challenge[0].challengeId;
challenge_obj.description = challenge[0].description;
challenge_obj.date = challenge[0].image.date;
challenge_obj.img = challenge[0].image.img;
// Save the challenges into the challenge array.
challenge_arr.push(challenge_obj);
console.log(i)
/* If the loop is in the last round, return the filled
array.*/
if (i == result.length - 1) {
// Return the filled array.
return challenge_arr;
}
})
.then(challenge_arr => {
// Check that the array isn't undefined.
if (typeof challenge_arr !== "undefined") {
// Resolve the promise.
resolve(challenge_arr);
}
});
}
}
});
});
// Call promise function and send a response after resolving it.
myPromise().then(data => {
res.status(200).json({ data: data });
});
}
];
var EntrySchema = new Schema({
challengeId: ObjectId,
userId: ObjectId,
date: { type: Date, default: Date.now},
img: { data: Buffer, contentType: String}
})
var ChallengeSchema = new Schema({
challengeId: mongoose.SchemaTypes.ObjectId,
title: String,
description: String,
date: {type: Date}
})
У меня есть две записи в коллекции Entries, которые имеют те же идентификаторы вызова, что идве проблемы в сборе вызовов.Я запрашиваю коллекцию запросов с идентификаторами записей, и я должен получить 2 документа, к которым добавлено соответствующее поле ввода.Иногда я правильно получаю документы, но в большинстве случаев возвращает только некоторые из них.Например, из 4 ожидаемых документов возвращается {chall 1, null, chall 2, chall 3}.