admin管理员组文章数量:1201370
The following code works with no querystrings or one querystring only. In other words, simply going to /characters
returns all characters. But if you were to specify a querystring parameter /characters?gender=male
it will return only male characters.
How could I extend this to work with either 1, 2, 3, or no querystrings? I would really prefer to avoid writing 8 or 9 different if-statements for each case. I was hoping Mongoose would simply ignore a $where clause if it's null
or undefined
, but that is not the case (see commented out code).
var gender = req.query.gender;
var race = req.query.race;
var bloodline = req.query.bloodline;
var query = Character.find();
if (gender)
query = query.where('gender').equals(gender);
if (race)
query = query.where('race').equals(race);
if (bloodline)
query = query.where('bloodline').equals(bloodline);
/*
query
.where('gender').equals(new RegExp('^' + gender + '$', 'i'))
.where('race').equals(new RegExp('^' + race + '$', 'i'))
.where('bloodline').equals(new RegExp('^' + bloodline + '$', 'i'));
*/
query.exec(function(err, characters) {
if (err) throw err;
res.send(characters);
});
Edit: Well I guess I could do it with 7 if-statements for now. Unless someone finds a more elegant solution.
Edit 2:
Thanks guys. It's difficult to pick one answer because both of you have helped me to achieve this concise solution. Here is the entire thing now.
var conditions = {};
for (var key in req.query) {
if (req.query.hasOwnProperty(key)) {
conditions[key] = new RegExp('^' + req.query[key] + '$', 'i');
}
}
var query = Character.find(conditions);
query.exec(function(err, characters) {
if (err) throw err;
res.send({ characters: characters });
});
The following code works with no querystrings or one querystring only. In other words, simply going to /characters
returns all characters. But if you were to specify a querystring parameter /characters?gender=male
it will return only male characters.
How could I extend this to work with either 1, 2, 3, or no querystrings? I would really prefer to avoid writing 8 or 9 different if-statements for each case. I was hoping Mongoose would simply ignore a $where clause if it's null
or undefined
, but that is not the case (see commented out code).
var gender = req.query.gender;
var race = req.query.race;
var bloodline = req.query.bloodline;
var query = Character.find();
if (gender)
query = query.where('gender').equals(gender);
if (race)
query = query.where('race').equals(race);
if (bloodline)
query = query.where('bloodline').equals(bloodline);
/*
query
.where('gender').equals(new RegExp('^' + gender + '$', 'i'))
.where('race').equals(new RegExp('^' + race + '$', 'i'))
.where('bloodline').equals(new RegExp('^' + bloodline + '$', 'i'));
*/
query.exec(function(err, characters) {
if (err) throw err;
res.send(characters);
});
Edit: Well I guess I could do it with 7 if-statements for now. Unless someone finds a more elegant solution.
Edit 2:
Thanks guys. It's difficult to pick one answer because both of you have helped me to achieve this concise solution. Here is the entire thing now.
var conditions = {};
for (var key in req.query) {
if (req.query.hasOwnProperty(key)) {
conditions[key] = new RegExp('^' + req.query[key] + '$', 'i');
}
}
var query = Character.find(conditions);
query.exec(function(err, characters) {
if (err) throw err;
res.send({ characters: characters });
});
Share
Improve this question
edited Jul 28, 2014 at 9:22
Preview
35.8k10 gold badges94 silver badges113 bronze badges
asked Oct 30, 2013 at 20:19
Sahat YalkabovSahat Yalkabov
33.6k44 gold badges113 silver badges176 bronze badges
3
- No problem, but you should pick an answer for future users to know which helped you more. If you can't, think about writing your own answer and checking that one as correct. – cschaeffler Commented Oct 30, 2013 at 21:31
- 1 You should remove your Edit 2 and write your own answer, that is great btw – Preview Commented Jul 28, 2014 at 9:21
- Very nice - works great; except for the sanitation part with the RegEx which produces odd queries. – Stephan K. Commented Feb 23, 2015 at 14:37
3 Answers
Reset to default 13You don't need to call Query#where
repeatedly, since you can pass all the conditions to Mongoose Model#find as:
var filteredQuery = {},
acceptableFields = ['gender', 'race', /* etc */ ];
acceptableFields.forEach(function(field) {
req.query[field] && filteredQuery[field] = req.query[field];
});
var query = Character.find(filteredQuery);
You'll also want to sanitize req.query
depending on the allowed parameters you have in mind.
I am using destructing of objects for this task.
const filter = req.query.filter ? { _id: { $in: req.query.filter.split(',') } } : {};
const category = req.query.category ? { category: req.query.category } : {};
// more variables that you need and are empty objects if don't exist
const all = await Post.find({ ...filter, ...category }).exec();
Well,
I would recommend something like this:
var query = Character.find()
if(req.params.length < 0) {
for(var key in req.params) {
query.where(req.params[key]).equals(key);
}
} else {
// do something without query params
}
this is not tested by me but it should work (maybe you need to modify it a bit but you get the idea). This solution is all about not checking what actually is in the params so be sure only good stuff comes in or validate it somewhere in the for loop, but would require some regex or if statements.
Hope this helps you.
本文标签: javascriptHow to build a conditional query in MongooseStack Overflow
版权声明:本文标题:javascript - How to build a conditional query in Mongoose? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738604335a2102257.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论