背景
在我开发在线答题小程序的过程中,会经常使用到聚合aggregate和数据查询get,比如从题库抽题、付费解锁、排行榜等。
聚合aggregate和数据查询get时不同的两套体系,聚合更偏向于数据的统计分析。
由于聚合和数据查询都能对数据库进行查询,而且两个的很多方法都特别类似,所以我刚开始的时候会混淆,甚至错误的混用,比如会在aggregate()加where条件、get请求,这里为了让自己更好理解,特整理一下两个的对比,我在写数据库查询和聚合时都会先写类似以下的模板。
普通数据查询
const db = wx.cloud.database() //获取数据库的引用
const _ = db.command //获取数据库查询及更新指令
db.collection("question") //获取集合china的引用
.where({ //查询的条件指令where
create_time: _.gt(1598580712652) //查询筛选条件,gt表示字段需大于指定值。
})
.field({ //显示哪些字段
_id:false, //默认显示_id,这个隐藏
subject: true,
answer: true,
options:true
})
.orderBy('create_time', 'desc') //排序方式,降序排列
.skip(0) //跳过多少个记录(常用于分页),0表示这里不跳过
.limit(10) //限制显示多少条记录,这里为10
.get() //获取根据查询条件筛选后的集合数据
.then(res => {
console.log(res.data)
})
.catch(err => {
console.error(err)
})
聚合查询
const db = wx.cloud.database()
const _ = db.command
const $ = db.command.aggregate
db.collection('china').aggregate()
.match({ //类似于where,对记录进行筛选
price: $.gt(3000)
})
.project({ //类似于field
})
.sort({ //类似于orderBy
age: -1,
score: -1
})
.skip(5) //类似于skip
.limit(2) //类似于limit
.end()
.then(res => console.log(res))
.catch(err => console.error(err))
总结
- match是根据条件过滤文档,进行的是查询匹配,语法和where比较类似,在写聚合时,应尽可能的把match放在流水线的前面。match内可以写db.command查询操作符
_
和聚合操作符db.command.aggregate$
,但是除了match阶段,在其他聚合阶段中传入的对象可使用的操作符都是聚合操作符; - project 把指定的字段传递给下一个流水线,指定的字段可以是某个已经存在的字段,也可以是计算出来的新字段,它和field不同的是可以新增一些不存在的字段(只是显示用,也没写进数据库);
- sort 根据指定的字段,对输入的文档进行排序。<排序规则>可以是以下取值:1 代表升序排列(从小到大);-1 代表降序排列(从大到小);功能和orderBy类似;
- 小程序端 limit 默认 20,也就是如果你使用聚合查询,你查询到的数据都会默认显示20条数据,但是你可以设置更多,而普通查询是不能超过20条的。
还是没看懂,有空实践下
db.collection('userDataTest').aggregate() .project({ data: '$secrets', mark: agg.cond({ if: agg.isArray('$secrets'), then: "", else: "标记8" }), }) .match( { mark: "标记8" } ) .end() 像这种语句查询出整个记录中secrets不是数组的记录,后续怎么批量删除该字段,或者更新成空数组呀?
聚合查询之后能对聚合查询的结果增删改查吗