Node.js 有条件地使用skip和limit的请求参数
我已经为我的restful API实现了“限制”和“跳过”查询 如果我试着去做 'localhost:4000/api/users?skip=60',它将跳过我的数据中的前60项 及 'localhost:4000/api/users?limit=5'将只返回5个数据 然后把这两者结合起来 'localhost:4000/api/users?skip=60&limit=5'将跳过前60个数据,并从该点返回5个数据 我的跳过和限制实现为:Node.js 有条件地使用skip和limit的请求参数,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我已经为我的restful API实现了“限制”和“跳过”查询 如果我试着去做 'localhost:4000/api/users?skip=60',它将跳过我的数据中的前60项 及 'localhost:4000/api/users?limit=5'将只返回5个数据 然后把这两者结合起来 'localhost:4000/api/users?skip=60&limit=5'将跳过前60个数据,并从该点返回5个数据 我的跳过和限制实现为: router.get('/', function(req,
router.get('/', function(req, res) {
var skipping = req.query.skip;
var limiting = req.query.limit;
// skipping
if(skipping != null){
user.find({})
.skip(3)
.exec(function(err, users) {
if(err){
res.status(404).send({
message: err,
data: []
});
} else {
res.status(200).send({
message: 'OK skipped',
data: users
});
}
});
}
// limit
else if(limiting != null){
user.find({})
.limit(parseInt(limiting))
.exec(function(err, users) {
if(err){
res.status(404).send({
message: err,
data: []
});
} else {
res.status(200).send({
message: 'OK limited',
data: users
});
}
});
}
}
});
每一个都很好,但是当我试图通过改变else if to if来组合它们时,应用程序崩溃并发出一条消息
错误:发送邮件后无法设置邮件头。
如何组合这些查询而不出错?不要为每个参数更改重写代码。和修饰符基本上修改了“光标”并可以“链接”。更具体地说,使用mongoose时,它们返回一个
Query
对象,在发出之前,您只需“链接”。或者只需使用“默认值”:
使用默认值:
router.get('/', function(req, res) {
var skipping = parseInt(req.query.skip) || 0;
var limiting = parseInt(req.query.limit) || 0;
user.find().skip(skipping).limit(limiting).exec(...);
})
或“链接”:
这是“方法链接”,您实际上“一直”使用它,只是您没有意识到您正在使用它。例如,如果没有if
条件:
let query = user.find().skip(0).limit(0);
与写作完全相同:
let query = user.find();
query = query.skip(0);
query = query.limit(0);
在第一种形式中,每个“修饰符”find()
、skip()
和limit()
都会根据给定的输入对象返回一个查询对象。它们“返回到左边”,因为它们只是一个函数,而这正是使您能够“链接”的原因。因此,“单独”编写赋值是非常必要的就实际完成的作业而言,“完全一样”
无论如何,req.params
值要么存在要么未定义
和不null
,就像您当前尝试做的那样。因此调用res.send()
两次都会出错
但您甚至不需要重复发出查询的代码。只需使用如图所示的任一方法执行一次即可。不必为每次参数更改重写代码。和修饰符基本上修改“光标”,并且可以“链接”。更具体地说,使用mongoose时,它们返回一个查询
对象,在发出之前,您只需“链接”该对象。或者只使用“默认值”:
使用默认值:
router.get('/', function(req, res) {
var skipping = parseInt(req.query.skip) || 0;
var limiting = parseInt(req.query.limit) || 0;
user.find().skip(skipping).limit(limiting).exec(...);
})
或“链接”:
这是“方法链接”,你实际上“一直”在使用它,只是你没有意识到你在使用它。例如,没有if
条件:
let query = user.find().skip(0).limit(0);
与写作完全相同:
let query = user.find();
query = query.skip(0);
query = query.limit(0);
在第一种形式中,每个“修饰符”find()
、skip()
和limit()
都会根据给定的输入对象返回一个Query
对象。它们“返回到左边”,因为它们只是一个函数
,这使您能够“链接”。所以,就实际完成的作业而言,“单独”写作业是“完全相同的事情”
无论如何,req.params
值要么存在要么未定义
和不null
,就像您当前尝试做的那样。因此,两次调用res.send()
时出错
但您甚至不需要重复发出查询的代码。只需使用如图所示的任何一种方法“一次”即可。我尝试了您的“链接”选项,效果很好!但我不太明白这个解决方案是如何运作的如果此行中的(跳过)query=query.skip(parseInt(跳过)),是否会增加查询的字符串值,以便连接所有查询选项?@Dawn17否它“修改”请求的实际发送方式。在您
.exec()
之前,实际上什么都不会发生,而这正是您似乎没有掌握的部分。就我个人而言,我会为这类事情设置“默认值”,但“理解”组件的实际工作方式是很有用的。“查询”在您实际“执行”它之前只是一个“查询”。我的意思是,如果跳过和限制都存在,那么查询是否会被“query=query.limit(parseInt(limiting))”替换,因为它发生在如果(跳过)
之后?@Dawn17不是“替换”而是“追加”。这些是“选项”,正如我已经两次解释的那样,“在执行之前,不会向服务器发送任何内容”。因此,如果“两者”都存在,那么它们都适用。我想如果我想得到技术性的,你会选择if(跳过!=未定义)
,因为0
也是一个“假”值。但我们讨论的是,你是否真的发送了参数,而不是它们的“值”。还有“阅读文档”,这就是我在答案中添加链接的原因.sklip()
和limit()
具有“返回值”,这是“修改过的”对象。@Dawn17count()
也是一个修饰符。事实上,我在答案中添加了更多的文字来解释“方法链接”实际上是什么,以及你实际上是如何一直使用它的,但似乎没有意识到这就是你正在做的事情。我尝试了你的“链接”选项,结果成功了!但我不太明白这个解决方案是如何运作的如果此行中的(跳过)query=query.skip(parseInt(跳过)),是否会增加查询的字符串值,以便连接所有查询选项?@Dawn17否它“修改”请求的实际发送方式。在您.exec()
之前,实际上什么都不会发生,而这正是您似乎没有掌握的部分。就我个人而言,我会为这类事情设置“默认值”,但“理解”组件的实际工作方式是很有用的。“查询”在您实际“执行”它之前只是一个“查询”。我的意思是,如果跳过
和限制
都存在,那么query
会被“query=query.limit(parseInt(limiting))”取代吗