索引
说明:索引是为了加快查询速度,可以对集合中的一列或多列设置索引。
– 无索引:扫描整个集合的文档,查找符合条件的文档
– 有索引:查找索引,根据索引取出文档数据
-
创建索引
db.<collection_name>.createIndex(keys, option)
栗子:
1
2
3
4
5
6
7
8
9
101. 单索引
db.user.createIndex({age:-1})
---
age:索引列名
-1:倒序索引
1:正序索引
2. 多索引(复合索引)
db.user.createIndex({age:1, gender:-1})- 可选参数
参数 类型 说明 background Boolean 指定创建索引时是否阻塞集合的其他操作。true:后台执行,不阻塞;false:阻塞,默认 unique Boolean 指定索引是否为唯一索引。true:唯一索引;false:不唯一,默认 name String 索引名称,默认为字段名+索引顺序 v index
version索引版本号,默认为当前mongo的版本号 weights Integer 1~99999之间,值越大权重越大 expireAfterSeconds Integer 指定集合生存时间。秒级,TTL sparse Boolean 指定是否忽略不存在的字段。true:不查出不包含查询字段的文档;false:查询所有文档,默认 栗子:
1
2
3
4
5> db.user.createIndex({name:1}, {background: true, unique: true, name: "idx_user_name", v: 1, weights: 99, sparse: true})
>
> ---
> 后台不阻塞集合的方式创建一个name列正序,版本号为1,权重99,忽略无name字段的文档的唯一索引idx_user_name
> -
查看所有索引
db.<collection_name>.getIndexes()
栗子:
db.user.getIndexes()
-
重建索引
-
方法1:
db.<collection_name>.reIndex()
-
方法2:先删除原索引,然后再创建
1
2db.<collection_name>.dropIndex(<idx_name>)
db.<collection_name>.createIndex(...)
-
-
删除索引
-
删除指定名称的索引:
db.user.dropIndex(<idx_name>)
-
删除集合中所有索引
db.user.dropIndexes()
说明:只会删除自建的索引,集合中_id列的索引不会被删除
-
聚合查询
1 | 创建集合并插入数据: |
格式:
1
2
3
4
5
6
7
8
9
10 db.<collection_name>.aggregate(condition)
---
condition:
[{$group:{_id:"$<key>", num_tutorial:{$<fun_expression>:"$<key>"}}}]
$group:一个组
_id:组合列,类同于MySQL的group by后面的字段,默认_id的列会在查询结果中显示
num_tutorial:输出的列名
$<fun_expression>:聚合表达式
$<key>:运算的列名
关键字:aggregate
说明:聚合查询就是求和、最大、最小、最前、最后、平均数的统称,类似于MySQL的count()、sum()、avg()
栗子:
1
2
3
4
5 > db.user.aggregate([{$group: ${_id:"$gender", num_tutorial:{$sum:1}}}])
>
> ---
> 等同于MySQL:select gender, count(1) from user group by gender
>
- 聚合表达式
表达式 | 描述 | 案例 |
---|---|---|
$sum | 计算总和 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$sum:"$likes"}}}]) — 等同于MySQL: select by_user, sum(likes) from agg group by by_user |
$avg | 计算平均值 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$avg:"$likes"}}}]) — 等同于MySQL: select by_user, avg(likes) from agg group by by_user |
$min | 获取集合中指定列的最小值记录 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$min:"$like"}}}]) — 等同于MySQL: select by_user, min(likes) from agg group by by_user |
$max | 获取集合中指定列的最大值记录 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$max:"$likes"}}}]) — 等同于MySQL: select by_user, max(likes) from agg group by by_user |
$push | 在结果文档中插入值到数组 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$push:"$url"}}}]) — 等同于MySQL:查出所有数据,然后取字段url写入同一个列表中,url不去重,然后输出 |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$addToSet:"$url"}}}]) — 等同于MySQL:查出所有数据,然后取字段url写入同一个列表中,url去重,然后输出 |
$first | 根据资源文档的排序获取第一个文档数据 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$first:"$title"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.agg.aggregate([{$group:{_id:"$by_user", num_tutorial:{$last:"$title"}}}]) |
管道函数
说明:管道函数类似于Linux系统中的管道操作,将上一步的运算结果作为下一步的输入值,最终达到理想计算结果的运算方式
函数 | 说明 |
---|---|
$project | 指定需要输出的列,默认显示_id,格式:{$project:{by_user:1, title:1, url:1, _id:0不显示id }}, |
$limit | 限制查询返回的文档数,格式:{$limit: 1},只返回一个文档 |
$skip | 跳过指定数量的文档,返回之后的所有文档,格式:{$skip: 1},从第二个文档开始输出 |
$match | 条件筛选,格式:{match: {likes: {gte: 10}}} |
$group | 聚合条件,格式:{group: {_id: "by_user", count: {$sum: -1}}} |
$sort | 排序,格式:{$sort: {likes: -1}},-1:倒序; 1:正序 |
$unwind | 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值 |
$geoNear | 输出接近某一地理位置的有序文档。 |
栗子:
1
2
3
4
5
6 db.agg.aggregate({$match: {likes: {$gte: 10}}}, { $project: {_id: 0, title: 1, by_user: 1, likes: 1}}, {$limit: 5}, {$skip: 1}, {$sort: {likes: -1}})
---
等同于MySQL:
select title, by_user, likes from agg where likes >= 10 order by likes desc limit 1,5