我有这个使用IOS创建的简单应用程序,它是一个问卷调查应用程序,每当用户点击播放时,它都会调用对node.js / express服务器的请求
从技术上讲,用户点击答案后会转到下一个问题
我很难使用哪种方法来获取问题/问题
API示例
// Fetch all the data at once
app.get(‘/api/questions’, (req, res, next) => {
Question.find({}, (err, questions) => {
res.json(questions);
});
});
// Fetch the data one by one
app.get('/api/questions/:id', (req, res, next) => {
Question.findOne({ _id: req.params.id }, (err, question) => {
res.json(question);
});
});
第一种方法的问题在于,假设有200个问题,mongodb一次获取并且可能慢于进行网络请求不会很慢
2号方法的问题,我无法想象如何做到这一点,因为每个问题都是独立的并且触发下一个api调用只是很奇怪,除非mongodb中有一个计数器或一个级别。
为了清楚起见,这是Mongoose中的数据库设计问题
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const QuestionSchema = new Schema({
question: String,
choice_1: String,
choice_2: String,
choice_3: String,
choice_4: String,
answer: String
});
答案 0 :(得分:1)
非常好的问题。我想这个问题的答案取决于你对这个应用程序的未来计划。
如果您计划有500个问题,那么逐个获取这些问题将需要500个api电话。总是不是最好的选择。另一方面,如果你一次获取所有这些,它将根据每个对象的大小延迟响应。
所以我的建议是使用分页。当用户达到第8个问题时,带来10个结果,用下面的10个问题更新列表。
这是移动开发人员的常见做法,这也使您可以根据用户之前的回复灵活地更新下一个问题。就像自适应测试一样。
修改强>
您可以添加pageNumber&请求中的pageSize查询参数,用于从服务器获取问题,如下所示。
myquestionbank.com/api/questions?pageNumber=10&pageSize=2
在服务器上接收这些参数
var pageOptions = {
pageNumber: req.query.pageNumber || 0,
pageSize: req.query.pageSize || 10
}
并且在从数据库查询时提供这些附加参数。
Question.find()
.skip(pageOptions.pageNumber * pageOptions.pageSize)
.limit(pageOptions.pageOptions)
.exec(function (err, questions) {
if(err) {
res.status(500).json(err); return;
};
res.status(200).json(questions);
})
注意:以零(0)开始你的pageNumber它不是强制性的,但这是惯例。
skip()
方法允许您跳过前n个结果。考虑第一种情况,pageNumber将为零,因此乘积(pageOptions.pageNumber * pageOptions.pageSize
)将变为零,并且它不会跳过任何记录。
但是对于下一次(pageNumber = 1),产品将导致10.因此它将跳过已经处理的前10个结果。
limit()
此方法会限制将在结果中提供的记录数。
请记住,您需要为每个请求更新pageNumber变量。 (虽然你也可以改变限制,但建议在所有请求中保持相同)
因此,您所要做的就是,只要用户遇到倒数第二个问题,您就可以从服务器请求10(pageSize)更多问题,并将其放入数组中。
代码参考:here。
答案 1 :(得分:1)
我会使用Dave的方法,但我会在这里详细介绍一下。
在您的应用中,创建一个包含问题的数组。然后还存储一个用户当前所在问题的值,例如将其称为index
。然后,您有以下伪代码:
index = 0
questions = []
现在你有了这个,一旦用户启动应用程序,加载10个问题(参见Dave的回答,使用MongoDB的跳过并限制),然后将它们添加到数组中。向您的用户提供questions [index]
服务。一旦索引达到8(=第9个问题),通过API加载10个问题,并将它们添加到数组中。这样,您将始终可以为用户提供问题。
答案 2 :(得分:0)
你可以在mongodb中使用limit和skip的概念。
当你第一次点击api时,你可以让你的限制= 20,并且每次再次使用api时,skip = 0会增加你的跳过次数。
第1次=> limit = 20,skip = 0
当您点击下一个=> limit = 20,skip = 20等等
string_agg(t2.name, ',' order by t2.name)
答案 3 :(得分:0)
你是对的,我认为第一个选项是never-to-use
选项。如果没有使用或有机会不在上下文中使用,那么获取那么多数据是没用的。
你可以做的是你可以公开一个新的api电话:
app.get(‘/api/questions/getOneRandom’, (req, res, next) => {
Question.count({}, function( err, count){
console.log( "Number of questions:", count );
var random = Math.ceil(Math.random() * count);
// random now contains a simple var
now you can do
Question.find({},{},{limit:1,skip:random}, (err, questions) => {
res.json(questions);
});
})
});
skip:random
将确保每次提取随机问题。这只是如何从所有问题中获取随机问题的基本概念。您可以进一步提供逻辑,以确保用户没有得到他在之前步骤中已经解决的任何问题。
希望这会有所帮助:)