2

我正在构建一个流星应用程序,将问题消息存储在数据库中。您可以请求包含消息的列表,但您也可以搜索消息。共有三个搜索字段:日期、患者 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 条件构建搜索查询,而不会产生太多开销?

谢谢。

4

2 回答 2

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);
于 2013-08-06T13:10:58.337 回答
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
    }
};
于 2013-08-06T13:23:25.360 回答