【发布时间】:2019-06-16 17:13:16
【问题描述】:
我的数据库有三个集合,挑战,用户和条目。挑战具有标题、描述和挑战 ID 等字段。条目是已完成的挑战,包含用户 ID、挑战 ID 和图像等字段。我想将条目集合中的数据加入到相应的挑战中,这样我就可以拥有一个包含挑战标题、描述、挑战 ID 和图像的文档。 我正在尝试根据从条目集合中获取的 id 数组查询挑战集合,然后将条目查询结果作为新字段添加到文档中。 我已经实现了一个 for 循环,它允许我每次使用不同的 id 进行查询。我想将查询的结果添加到数组中,但有时它会跳过结果,结果数组中只存在一些查询。例如,当我第一次发送 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 集合中有两个条目,它们的挑战 ID 与挑战集合中的两个挑战相同。我用条目的 id 查询挑战集合,我应该得到 2 个添加了相应条目字段的文档。有时我会正确获取文档,但大多数时候它只返回其中的一些。例如,从 4 个预期文档中,它返回 {chall 1, null, chall 2, chall 3}。
【问题讨论】:
标签: javascript node.js mongodb rest