我正在构建一个将问题消息存储在数据库中的流星应用程序。您可以要求提供包含邮件的列表,但您也可以搜索邮件。有三个搜索字段:日期,患者ID和请求编号。可以搜索具有一个或多个字段的消息。响应是所有已完成字段相同的消息。因此我构建了以下查询:
Template.list.problems = function() {
var d = Session.get('search_on_date');
var p = Session.get('search_on_pid');
var r = Session.get('search_on_req');
var and_query = null;
if (d!=null && p==null && r==null) and_query = {'Problem.DateTime': RegExp('^'+d)};
if (d==null && p!=null && r==null) and_query = {'Problem.PID':p};
if (d==null && p==null && r!=null) and_query = {'Problem.Request':r};
if (d!=null && p!=null && r!=null) and_query = {$and: [{'Problem.DateTime': RegExp('^'+d)}, {'Problem.PID':p}, {'Problem.Request':r}]};
if (d!=null && p!=null && r==null) and_query = {$and: [{'Problem.DateTime': RegExp('^'+d)}, {'Problem.PID':p}]};
if (d==null && p!=null && r!=null) and_query = {$and: [{'Problem.PID':p}, {'Problem.Request':r}]};
if (d!=null && p==null && r!=null) and_query = {$and: [{'Problem.DateTime': RegExp('^'+d)}, {'Problem.Request':r}]};
return problems.find(and_query);
};
这个解决方案有效,我对此感到非常高兴。但我的问题是:是否有更有效的方法来构建查询?在这种情况下,我必须为已完成字段的每个可能组合制作一个if语句。因此只有三个字段是可能的,但是在许多字段的情况下,我认为必须有更好的解决方案。
所以我的问题是:如何以非常有效的方式构建具有AND条件的搜索查询,而不需要太多开销?
感谢。
答案 0 :(得分:1)
你可以这样做(伪代码):
clauses = [];
if (d!=null) clauses.push( {'Problem.DateTime': RegExp('^'+d)} );
if (p!=null) clauses.push( {'Problem.PID':p} );
if (r!=null) clauses.push( {'Problem.Request':r} );
if (clauses.length == 1) {
and_query = clauses[0];
} else {
and_query = {$and: clauses};
}
return problems.find(and_query);
答案 1 :(得分:0)
对于你的约会对象,我会给他们一个图形日期选择器并验证输入,然后使用javascript Date对象进行精确搜索,这比使用正则表达式快得多。
至于代码清理,我个人会做这样的事情:
var $and = [];
if(d) $and.push({'Problem.DateTime': new RegExp('^' + d)});
if(p) $and.push({'Problem.PID':p});
if(r) $and.push({'Problem.Request':r});
if($and.length > 0) {
if($and.length > 1) {
return problems.find({ $and: $and });
} else {
return problems.find($and[0]);
}
}
我认为编码风格/可读性完全取决于猜测,这就是我的做法。
日期的示例查询:
var startDate = new Date(); // user supplied date
var endDate = new Date(); // user supplied date again
endDate.setDate(endDate.getDate() + 1); // add a day
var query = {
'Problem.DateTime': {
$gte: startDate,
$lt: endDate
}
};