我应该在Mongoose中逐个返回数组或数据吗?
我有使用IOS创build的这个简单的应用程序,它是一个调查问卷应用程序,每当用户点击播放,它会调用一个请求,以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立即获取速度慢,可能networking请求速度慢
第二种方法的问题,我无法想象如何做到这一点,因为每个问题是独立的,并触发到下一个API调用只是很奇怪,除非在问题mongodb有一个计数器或一个级别。
只是为了清楚起见,这是Mongoose中的问题数据库devise
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 });
我会用Dave的方法,但是我会在这里详细介绍一下细节。 在你的应用程序中,创build一个包含问题的数组。 然后还存储一个用户当前正在提问的值,例如称之为index
。 您然后有以下伪代码:
index = 0 questions = []
现在您已经拥有了这个function,只要用户启动应用程序,就会加载10个问题(请参阅Dave的回答,使用MongoDB的skip和limit),然后将它们添加到数组中。 向用户提供questions [index]
。 只要索引达到8(=第9个问题),通过您的API加载10多个问题,并将其添加到数组。 这样,你将永远有问题的用户。
很好的问题。 我想这个问题的答案取决于你有关这个应用程序的未来计划。
如果您打算提出500个问题,那么逐个获取它们将需要500个API。 总是不是最好的select。 另一方面,如果一次抓取所有这些数据,它将根据每个对象的大小来延迟响应。
所以我的build议是使用分页。 带来10个结果,当用户到达第8个问题时,用下面的10个问题更新列表。
这是移动开发人员的常见做法,这也将使您能够灵活地根据以前的用户反馈更新下一个问题。 像自适应testing和所有。
编辑
您可以在请求中添加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
)将变为零,并且不会跳过任何logging。 但是,下一次(pageNumber = 1)产品将会变为10.所以它会跳过前10个已经处理的结果。
limit()
这个方法限制了结果中提供的logging数。
请记住,您需要更新每个请求的pageNumbervariables。 (尽pipe你也可以改变限制,但build议在所有请求中保持一致)
所以,你所要做的就是,只要用户到达第二个问题,就可以从服务器请求10个(pageSize)更多的问题,把它放在你的数组中。
代码参考: 这里 。
你是对的,我认为第一个选项也是一个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
将确保每次提取一个随机问题。 这只是一个基本的想法,如何从你的所有问题中获取一个随机问题。 你可以进一步的逻辑,以确保用户没有得到任何问题,他已经解决了在前面的步骤。
希望这可以帮助 :)
你可以使用限制的概念和在mongodb中跳过。
当你第一次打api的时候,你可以有你的限制= 20和skip = 0每次你再次增加你的跳过计数。
第一次=> limit = 20,skip = 0
当你点击next => limit = 20,skip = 20等等
app.get('/api/questions', (req, res, next) => { Question.find({},{},{limit:20,skip:0}, (err, questions) => { res.json(questions); }); });