Node.js中使用koa和MongoDB实现分页和模糊查询

1. 分页

    per_page:一页多少条数据 page:第几页
// index.js
const Koa = require(koa)
const app = new Koa()
const Router = require(koa-router)
const usersRouter = new Router({ prefix: /users})
// MongoDB数据库User模型
const User = require(/models/users.js)

const bodyparser = require(koa-bodyparser)
app.use(bodyparser()) 

// 用户列表
usersRouter.get(/, (ctx) => { 
    // 分页 http://localhost:3000/users?page=2&per_page=3
    const { per_page = 10 } = ctx.query
    const page = Math.max(ctx.query.page * 1, 1) - 1
    const perPage = Math.max(per_page * 1, 1)
    ctx.body = await User.find().limit(perPage).skip(page * perPage)
})

app.use(usersRouter.routes())
app.use(usersRouter.allowedMethods())
 
app.listen(3000)

2. 模糊查询

MongoDB中实现模糊查询要使用正则表达式

// index.js
const Koa = require(koa)
const app = new Koa()
const Router = require(koa-router)
const usersRouter = new Router({ prefix: /users})
// MongoDB数据库User模型
const User = require(/models/users.js)

const bodyparser = require(koa-bodyparser)
app.use(bodyparser()) 

// 用户列表
usersRouter.get(/, (ctx) => { 
    // 分页+模糊查询 http://localhost:3000/users?page=1&per_page=3&q=李
    const { per_page = 10 } = ctx.query
    const page = Math.max(ctx.query.page * 1, 1) - 1
    const perPage = Math.max(per_page * 1, 1)
    // 模糊查询,要用正则表达式
    ctx.body = await User.find({name:new RegExp(ctx.query.q)}).limit(perPage).skip(page * perPage)
})

app.use(usersRouter.routes())
app.use(usersRouter.allowedMethods())
 
app.listen(3000)

3. 字段过滤

select 用于显示在MongoDB数据库中select:false默认不显示,但是现在需要显示的数据

populate 用于关联查询

// index.js
const Koa = require(koa)
const app = new Koa()
const Router = require(koa-router)
const usersRouter = new Router({ prefix: /users})
// MongoDB数据库User模型
const User = require(/models/users.js)

const bodyparser = require(koa-bodyparser)
app.use(bodyparser()) 

// 根据用户id查询某个用户
usersRouter.get(/:id, (ctx) => { 
    // 字段过滤 http://localhost:3000/users/6268c33f5ecce8e573b27366?fields=educations;business
    const { fields =  } = ctx.query
    const selectFields = fields.split(;).filter(f => f).map(f =>  + + f).join( ) //注意这里是空格+
    const populateStr = fields.split(;).filter(f => f).map(f => {
        if (f === employments) {
            return employments.company employments.job
        }
        if (f === educations) {
            return educations.school educations.major
        }
        return f
    }).join( )
    const user = await User.findById(ctx.params.id).select(selectFields).populate(populateStr)
    if (!user) {
        ctx.throw(404, 用户不存在)
    }
    ctx.body = user
})

app.use(usersRouter.routes())
app.use(usersRouter.allowedMethods())
 
app.listen(3000)

4. koa中的ctx上下文对象

ctx,即context上下文对象,可以理解为上(request)下(response)沟通的环境,为了调用方便,koa中把request和response都封装进了ctx对象。

ctx下有四个属性:

    ctx.req:原生req对象 ctx.res:原生res对象 ctx.request:koa自己封装的request对象 ctx.response:koa自己封装的response对象

koa自己封装的对象与原生对象相比,使用方式更简便:

    ctx.query:原生对象需要使用url.parse(p,true).query才能得到的query对象 ctx.path:原生对象需要使用url.parse(p).pathname才能得到的路径(url去除query部分)

koa中常用ctx属性还有:

    ctx.query:获取解析的查询字符串, 当没有查询字符串时,返回一个空对象 ctx.params:获取动态路径参数 ctx.request.body:获取请求体 ctx.status:返回状态 ctx.body:响应体 ctx.throw:抛出错误 ctx.redirect:重定向

完整项目源码:

经验分享 程序员 微信小程序 职场和发展