我应该在Mongoose中逐个返回数组或数据吗?

我有使用IOS创build的这个简单的应用程序,它是一个调查问卷应用程序,每当用户点击播放,它会调用一个请求,以node.js / express服务器

在这里输入图像描述

在这里输入图像描述

技术上,用户点击答案后,将进入下一个问题

在这里输入图像描述

我很困惑使用哪种方法来获取问题/问题

  1. 一次获取所有数据并将其呈现给用户 – 这是一个数组
  2. 在用户进行下一个问题的过程中逐个获取数据 – 每次调用一个数据

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 }); 

       

网上收集的解决方案 "我应该在Mongoose中逐个返回数组或数据吗?"

我会用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); }); });