MongoDB基础应用

索引

说明:索引是为了加快查询速度,可以对集合中的一列或多列设置索引。

– 无索引:扫描整个集合的文档,查找符合条件的文档

– 有索引:查找索引,根据索引取出文档数据

  1. 创建索引

    db.<collection_name>.createIndex(keys, option)

    栗子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1. 单索引
    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
    >
  2. 查看所有索引

    db.<collection_name>.getIndexes()

    栗子:

    db.user.getIndexes()

  3. 重建索引

    • 方法1:db.<collection_name>.reIndex()

    • 方法2:先删除原索引,然后再创建

      1
      2
      db.<collection_name>.dropIndex(<idx_name>)
      db.<collection_name>.createIndex(...)
  4. 删除索引

    • 删除指定名称的索引:

      db.user.dropIndex(<idx_name>)

    • 删除集合中所有索引

      db.user.dropIndexes()

      说明:只会删除自建的索引,集合中_id列的索引不会被删除


聚合查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
创建集合并插入数据:
db.agg.save([{
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
}])

格式:

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
>
  1. 聚合表达式
表达式 描述 案例
$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
>