8

以下代码使用查询字符串或仅使用一个查询字符串。换句话说,只需/characters返回所有字符。但是,如果您要指定查询字符串参数/characters?gender=male,它将只返回男性字符。

我如何扩展它以使用123没有查询字符串?我真的更愿意避免为每个 case 编写 8 或 9 个不同的 if 语句。我希望 Mongoose 会简单地忽略$where子句,如果它是nullor undefined,但事实并非如此(请参阅注释掉的代码)。

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

编辑: 好吧,我想我现在可以用 7 个 if 语句来做到这一点。除非有人找到更优雅的解决方案。

编辑2:

多谢你们。很难选择一个答案,因为你们俩都帮助我实现了这个简洁的解决方案。这就是现在的全部内容。

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

3 回答 3

13

您不需要Query#where重复调​​用,因为您可以将所有条件传递给Mongoose Model#find,如下所示:

var filteredQuery = {},
  acceptableFields = ['gender', 'race', /* etc */ ];

acceptableFields.forEach(function(field) {
  req.query[field] && filteredQuery[field] = req.query[field];
});

var query = Character.find(filteredQuery);

您还需要req.query根据您考虑的允许参数进行消毒。

于 2013-10-30T21:00:46.530 回答
3

我正在使用破坏对象来完成这项任务。

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();
于 2019-07-01T13:46:07.890 回答
2

好,

我会推荐这样的东西:

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
}

我没有对此进行测试,但它应该可以工作(也许您需要对其进行一些修改,但您明白了)。这个解决方案就是不检查参数中的实际内容,因此确保只有好的东西进来或在 for 循环的某个地方验证它,但需要一些正则表达式或 if 语句。

希望这对您有所帮助。

于 2013-10-30T21:05:41.073 回答