聚合
特點:從多個文檔分組,在各個分組內進行多種操作,並返回結果
聚合有三種方式
- aggregation pipeline 管道聚合
- map-reduce
- single purpose aggregation methods 單一聚合
管道聚合 目前我常用的方式
文檔分別通過多級管道,管道內可以進行任何操作,並最終返回結果
例如:
db.admins.aggregate([
{
$match:{ //do somethings }
},
{
$group: { //do somethings }
}
])
管道聚合常用的操作符
- $group
- $match
- $lookup
- $project
- $sort
- $skip
- $limit
…….
管道聚合官方文檔
管道聚合優化
預測優化
- 原因:聚合會將整個集合全部放入管道中,這樣會降低速度而且可能會超過內存限制,所以如果只需要集合中部分數據,那麼僅僅傳入這些數據就可以
- 操作:主要是操作符爲: $match 和 $limit 放在一般操作的前面,減少後續的數據量
合併優化
- 同操作符的合併
- $lookup + $unwind 的合併
聚合管道的限制
結果集大小限制
BSON的限制:每個document不超過16MB,如果超過了,在管道內部不會報錯,但是返回結果集時會報錯
內存限制
管道內部允許佔用100MB的RAM,超過該內存時,mongodb會拋出錯誤,如果想使用大數據集合,可以使用 allowDiskUse選項開啓管道階段,數據寫入臨時文件
單一聚合
提供了 db.collection.count() 和 db.collection.distinct()
文本索引
特點:
- 快速執行文本查詢操作,支持多種匹配
- 支持所有字符串及字符串的數組
- 必須含有文本索引,且文本索引唯一
- 使用$test和$search檢索 $meta打分
創建文本索引
db.collection.createIndex({key:'text',key1:'text'....})
查找
db.collection.find({$test:{$search:''}})
一般檢索 匹配任意爲 name或age或sex的數據
db.collection.find({$test:{$search:'name age sex'}})
精確檢索 匹配任意爲 name或 age sex的數據
db.collection.find({$test:{$search:'name \'age sex\''}})
排除檢索 匹配任意爲 name或age且無sex的數據
db.collection.find({$test:{$search:'name age -sex'}})
計分:score根據匹配程度來打分
db.collection.find({$test:{$search:'name age sex'},score:{$meta: "textScore"}})
聚合管道使用
- 包含了$text 的 $match 階段必須是管道中的 第一個 階段。
- 操作符 $text 只能在階段中出現一次
- 操作符 $text 不能出現在 $or 和 $not 表達式中
- 默認地,文本搜索不會返回按照匹配得分的順序返回匹配文檔。可以選擇在 $sort 階段使用 $meta 聚合表達式。