从客户端控制器 (MEAN.JS) 指定 Mongo 查询参数

Posted

技术标签:

【中文标题】从客户端控制器 (MEAN.JS) 指定 Mongo 查询参数【英文标题】:Specifying Mongo Query Parameters From Client Controller (MEAN.JS) 【发布时间】:2014-09-08 17:57:19 【问题描述】:

我正在使用 MongoDB、Angular、Express 和 Node(MEAN 堆栈)构建应用程序。

我使用 MEAN.JS 生成器来搭建我的应用程序。

我将使用文章模块作为参考。

假设我的文章集合中有 7000 条记录,并且每条记录都有一个与之关联的日期。每次加载页面以查看表中的记录时,将所有 7000 条记录加载到内存中效率很低,因此我看到了可怕的性能损失。出于这个原因,我只想加载日期在(1 个月前)到(1 年后)范围内的记录,并将它们显示在表格中。我目前可以通过以下方式做到这一点:

在我的文章.client.controller.js 中:

$scope.find = function() 
        $articles = Articles.query();
;

...在我的文章中.server.controller.js:

var now = new Date();
var aYearFromNow = new Date(now.getTime() + 86400000*365); //add a year
var aMonthAgo = new Date(now.getTime() - 86400000*30); //subtract roughly a month

exports.list = function(req, res)  Article.find().where('date').lt(aYearFromNow).gt(aMonthAgo).sort('-created').populate('user', 'displayName').exec(function(err, articles) 
        if (err) 
            return res.send(400, 
                message: getErrorMessage(err)
            );
         else 
            res.jsonp(articles);
        
    );
;

问题在于这不是一种动态的做事方式。换句话说,我希望用户能够指定他们希望看到多远和多远。

如何在客户端视图中绑定变量(例如“aYearFromNow”和“aMonthAgo”)以更改服务器控制器中的查询参数?

【问题讨论】:

【参考方案1】:

这可能不是最干净的方式,但您可以创建一个新服务(或编辑当前服务以使用多个参数):

.factory('ArticlesService2', ['$resource',
    function($resource) 
        return $resource('articles/:param1/:param2', 
            param1: '',
            param2: ''
        , 
            update: 
                method: 'PUT'
            
        );
    
]);

然后在你的控制器中调用它:

$scope.findWithParams = function() 
    $scope.article = ArticlesService2.query(
        param1: $scope.aYearFromNow,
        param2: $scope.aMonthAgo
    );
;

在后端,您需要准备一条路线:

app.route('/articles/:param1/:param2')
    .get(articles.listWithParams)

给你的后端控制器添加一个函数:

exports.listWithParams = function(req, res) 
    Article.find()
    .where('date')
    .lt(req.params.param1)
    .gt(req.params.param2)
    .sort('-created').populate('user', 'displayName')
    .exec(function(err, articles) 
        if (err) 
            return res.send(400, 
                message: getErrorMessage(err)
            );
         else 
            res.jsonp(articles);
        
    );
;

应该可以,不过还没有测试过。

【讨论】:

【参考方案2】:

另一种方法是只在查询方法中传递搜索参数,如下所示:

 $scope.searchart = function() 
    Articles.query(start:$scope.startDate, end:$scope.endDate, function(articles) 
        $scope.articles = articles;
    );
;

然后在服务器端控制器,读取查询字符串参数,如下所示:

exports.searcharticle = function(req, res) 
    Article.find().where('date').gt(req.query['start']).lt(req.query['end']).exec(function(err, articles) 
        if (err) 
            res.render('error', 
                status: 500
            );
         else 
            res.jsonp(articles);
        
    );
;

这种方式不需要更多的路线或服务。

【讨论】:

这是一种更简洁的处理方式,不需要添加路由和混乱的服务器端。通过使用查询,您可以通过有条件地添加 mongoose 参数来保持列表方法的通用性。

以上是关于从客户端控制器 (MEAN.JS) 指定 Mongo 查询参数的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 3.0+安全权限访问控制

具有依赖项的 registerModule

RESTful Crud MEAN.js 路由

在 MEAN.JS 堆栈中运行 jQuery 代码

使用 MEAN.JS 用户授权

MEAN.JS,高延迟/在 Web 开发中找到瓶颈的方法