如何将数据库服务与分页和过滤隔离

时间:2019-07-19 16:50:33

标签: node.js mongodb rest mongoose

我正在从事一个相对较大的项目,该项目具有很多服务并查询数据库。在大多数项目中,有一项功能可以过滤结果搜索

我想知道如何拥有一个功能或模块来处理所有服务中的所有搜索,而不必在所有服务中编写相同(有点相同)的代码。

例如,我有一个返回流行歌曲的功能:

module.exports.get_trending_songs = async (req, res, next) => {
        var searchParams = {}
        var sortParams = {}
        if (req.query.search) {
            searchParams = {
                name: new RegExp('.*' + req.query.search + '.*', "i")
            }
        }
        if (req.query.sort) {
            sortParams = (req.query.order == 1 ? '' : '-') + req.query.sort
        }
        var songs
        songs = await Song.find(searchParams)
            .limit(parseInt(req.query.limit))
            .skip(parseInt(req.query.skip))
            .sort(sortParams)
            .exec()
}

我有一个返回用户的函数:

module.exports.get_users = async (req, res) => {
    var searchParams = {}
    var sortParams = {}
    if (req.query.search != undefined) {
        searchParams = {
            name: new RegExp('.*' + req.query.search + '.*', "i")
        }
    }
    if (req.query.sort != undefined) {
        sortParams = (req.query.order == 1 ? '' : '-') + req.query.sort
    }
    var users = await User.find(searchParams)
        .select('-password')
        .limit(parseInt(req.query.limit))
        .skip(parseInt(req.query.skip))
        .sort(sortParams)
        .exec()
}

正如您所看到的,它们几乎相同! (假设我通过执行相同的查询并向其中添加.count()来返回分页内容(例如nPages或countOfDocs)

在其他模块中处理所有副查询(分页,搜索等)并使服务仅专注于主查询的最佳方法是什么?不是

1 个答案:

答案 0 :(得分:1)

那些Mongoose函数返回一个Query object,您可以轻松地传递它...因此您可以编写一个函数,该函数接受一些事情(例如Model和req参数)并执行所有常用方法,但是然后在main方法中执行exec(),以便您可以处理任何其他内容(例如,从返回的字段中删除密码)。

以下是可能有效的示例,但我尚未对此进行测试 ...,因此您可能需要修改它。

function build_query = function(model, reqParams) {
    var searchParams = {}
    var sortParams = {}
    if (reqParams.search != undefined) {
        searchParams = {
            name: new RegExp('.*' + reqParams.search + '.*', "i")
        }
    }
    if (reqParams.sort != undefined) {
        sortParams = (reqParams.order == 1 ? '' : '-') + reqParams.sort
    }
    var query = model.find(searchParams)
        .select('-password')
        .limit(parseInt(reqParams.limit))
        .skip(parseInt(reqParams.skip))
        .sort(sortParams)
    return query
}

module.exports.get_users = async (req, res) => {
    var query = build_query(User, req.query)
    var users = await query.select('-password').exec()
}

module.exports.get_trending_songs = async (req, res, next) => {
    var query = build_query(Song, req.query)
    var songs = await query.exec()
}