MongoDB是一个基于分布式文件存储的文档式数据库.其由C++编写, 旨在为Web应用提供可扩展的高性能数据存储解决方案.

MongoDB中每条数据记录被作为一个文档存储,文档由集合(collection)进行管理, 每个数据库(db)下包含多个集合.

这与关系型数据库记录,数据表,数据库的关系类似, 但是同一个collection下的文档可以存储格式不同的数据,更加灵活.

首先我们在Ubuntu上安装MongoDB:

sudo apt-get install mongodb

MongoDB的数据需要存储在dbpath目录下, MongoDB默认以/data/db作为dbpath.

该目录不会在安装过程中自动创建, 需要手动chua创建:

sudo mkdir -p /data/db

启动MongoDB服务:

mongod

使用dbpath参数指定目录:

mongod --dbpath path

使用--rest参数启动Web管理界面支持.

MongoDB Shell是MongoDB自带的交互式Javascript shell:

mongo

因为这是个js shell可以在这里用js进行交互操作.

MongoDB默认用27017端口提供服务, Web界面的端口比服务端口多1000, 即28017端口.

在浏览器中访问http://localhost:28017即可打开MongoDB的Web界面.

MongoDB中最顶层的容器为数据库(db), 使用show dbs命令查看所有数据库:

> show dbs
local 0.078125GB

use指令用于切换到指定数据库, 当该数据库不存在时则自动创建:

> use test
switched to db test

成功切换到数据库后, db对象代表当前数据库:

> db
test

调用dropDatabase()删除数据库:

> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }

访问db对象的成员为集合, 访问一个不存在的集合将会自动创建:

> db.user
test.user

若要在创建时指定参数可以使用db.createCollection(name, options)

调用drop()方法清空集合:

> db.user.drop()
true

当集合中不含文档时会被自动删除.

文档操作

文档是MongoDB中数据的单位, 每个文档是采用BSON(Binary JSON)存储的字典.

文档由集合进行管理,

添加文档

使用insert()方法添加文档:

> doc = ({username:'filey', password:'1234'});
{ "username" : "filey", "password" : "1234" }
> db.user.insert(doc)

save()方法用于保存文档更改, 当文档不存在时自动创建:

> db.user.insert(doc)
> db.user.save(doc)
> db.user.insert(doc)
E11000 duplicate key error index: test.user.$_id_ dup key: { : ObjectId('57d77ba9a78dc753c19b1cc0') }
> db.user.save(doc)

查找文档

find()方法可以查看集合中的文档:

> db.user.find()
{ "_id" : ObjectId("57d77b87a78dc753c19b1cbf"), "username" : "first", "password" : "1234" }
{ "_id" : ObjectId("57d77ba9a78dc753c19b1cc0"), "username" : "second", "password" : "1234" }

可以根据文档中的属性值进行查询:

> db.user.find({'username':first})
{ "_id" : ObjectId("57d77b87a78dc753c19b1cbf"), "username" : "first", "password" : "1234" }

pretty()方法可以优化显示:

> db.user.find().pretty()
{
"_id" : ObjectId("57d77b87a78dc753c19b1cbf"),
"username" : "first",
"password" : "1234"
}
{
"_id" : ObjectId("57d77ba9a78dc753c19b1cc0"),
"username" : "second",
"password" : "1234"
}

与SQL类似, MongoDB的查询支持更复杂的条件:

功能 MongoDB SQL
等于 find({attr:val}) where attr = val
小于 find({attr:{$lt:val}}) where attr < val
小于等于 find({attr:{$lte:val}}) where attr <= val
大于 find({attr:{$gt:val}}) where attr > val
大于等于 find({attr:{$gte:val}}) where attr >= val
不等于 find({attr:{$ne:val}}) where attr != val

可以发现除了最简单的等于外,其它的表达式val都是用字典表示, 字典中的多个键表示与的关系:

find(attr:{$gt:lower, $gt:upper})

上述表达式等价于: where attr > lower and attr < upper. or条件的表达:

find({
attr: {
$or: [
{'&lt': upper},
{'&ne', bidden}
]
}
})

$type用于根据BSON中的数据类型进行筛选:

find({attr:{$type:1}})

上面的查询限定了attr的类型为double.

数字与类型之间的对照见下表:

  1. Double

  2. String

  3. Object

  4. Array

  5. Binary Data

  6. Undefined (已废弃)

  7. ObjectId

  8. Boolean

  9. Date

  10. Null

删除文档

remove(query, [option])方法用于删除文档, query与find的参数相同, 用于表达查询条件.

option是描述选项的字典:

db.collection.remove(
query,
{
justOne: false,
writeConcern: {}
}
)

justOne为true只删除查询到的第一个结果, 否则删除所有结果; writeConern表示日志的级别.

使用{}表示删除所有文档:

db.collection.remove({})

更新文档

除了save方法可以强制更新文档外, update方法可以实现更灵活的文档更新:

db.collection.update(query, update, [option])

query是表达查询条件的字典, 与find相同.

update为描述更新操作的字典, 其key有$set$inc等分别代表设置,添加键值对等操作.

option为表示选项的字典:

{
upsert: false,
multi: false,
writeConcern: {}
}

upsert为true表示在文档不存在时新建文档, 默认为false.

multi为false时只修改查询到的第一个文档,否则修改查询到的所有文档, 默认为false.

writeConcern表示日志的级别.

limit, skip 与 sort

limit方法用于限制结果集中文档的数量:

db.collection.find().limit(num)

num表示返回结果集中前num个文档, 若num大于总数则返回整个结果集.

skip用法与limit类似:

db.collection..find().skip(num)

num表示跳过结果集中前num个文档, 返回后面的文档.

limit和skip都是与顺序有关的查询操作, 所以我们需要排序方法和它们配合使用.

sort方法用于进行排序:

db.collection.find().sort({key1:1, key2:-1,})

key表示作为排序依据的属性, 1表示升序排列, -1表示降序排列.

在key1相同的情况下, 按照key2的规则进行排序.

默认情况下按照objectId进行升序排列.

aggregate

聚合(aggregate)操作用于获得集合或结果集的和,平均值等统计量.

db.collection[.find()].count(query)

count接受一个代表查询规则的字典, 返回满足条件的文档的个数.可以对集合或者结果集应用该方法.

db.collection.distinct(key)

distinct函数返回所有key指定属性的列表并删除重复:

> db.user.distinct('username')
[ "first", "second" ]

distinct只能对集合使用, 不能对结果集使用.

上面两个函数都只能进行及其简单的聚合操作, aggregate方法可以完成复杂的聚合操作.

db.collection.aggregate(ops)

ops参数为列表, 其中的元素为代表一次聚合操作的字典. 第一次操作的结果作为第二次操作的输入, 如此形成聚合管道.

首先准备一个测试集合;

> db.user.insert({username:'first', score:98})
> db.user.insert({username:'first', score:88})
> db.user.insert({username:'second', score:58})
> db.user.insert({username:'third', score:98})
> db.user.insert({username:'forth', score:95})

执行聚合管道操作:

db.user.aggregate([
{ $match:
{score: {$gte: 60}}
},
{ $group:
{ _id: '$username', avg: {$avg: '$score'} }
}
])

首先执行match操作, 筛选score>=60的文档:

{username:'first', score:98}
{username:'first', score:88}
{username:'third', score:98}
{username:'forth', score:95}

group操作进一步过滤上述结果集, 按照username分组, 计算每组score的平均值输出为avg:

"result" : [
{
"_id" : "forth",
"avg" : 95
},
{
"_id" : "third",
"avg" : 98
},
{
"_id" : "first",
"avg" : 93
}
],
"ok" : 1
}

上述语句等价于SQL语句:

select avg(score) as "avg"
from db.user
where score >= 60;

以上文的键值对$match:{score: {$gte: 60}}为例,$match称为管道操作符, {score: {$gte: 60}称为管道表达式.

下面介绍一些常用的管道操作:

$project

投影, 选择特定属性.其表达式为字典, 键为属性名, 值为1的键被保留,0和未指定的被过滤:

db.user.aggregate({
$project: {
_id: 1,
}
})

结果:

{
"result" : [
{
"_id" : ObjectId("57db67663364fa058d0ac911")
},
],
"ok": 1
}

$match

匹配, 筛选特定文档.match的管道表达式与find的query字典相同.

db.user.aggregate({
$match: {
score: {$gte: 60},
}
})

结果:

{
"result" : [
{
"_id" : ObjectId("57db67663364fa058d0ac911"),
"username" : "first",
"score" : 98
},
{
"_id" : ObjectId("57db676e3364fa058d0ac912"),
"username" : "first",
"score" : 88
},
],
"ok" : 1
}

$limit

限制文档的个数.管道表达式为正整数:

db.user.aggregate({$limit: 2 })

$skip

跳过指定个数的文档, 管道表达式为正整数:

db.user.aggregate({$skip: 2 })

$sort

对文档按照指定的属性排序, 管道表达式与sort()方法参数一致.

db.user.aggregate({
$sort: {score: 1, username: 1}
})

$unwind

将含有多值属性的文档拆分为多个只有单值属性的文档:

>db.article.insert(
{
name: 'First to MonogoDB',
author: 'finley',
tags: ['technology', 'database', 'NoSQl']}
)
>db.article.aggregate({$unwind: '$tags'})

$unwind的管道表达式为$加字段名组成的字符串.

结果:

{
"result" : [
{
"_id" : ObjectId("57db79f8dbf8a742aa6bc85f"),
"name" : "First to MonogoDB",
"author" : "finley",
"tags" : "technology"
},
{
"_id" : ObjectId("57db79f8dbf8a742aa6bc85f"),
"name" : "First to MonogoDB",
"author" : "finley",
"tags" : "database"
},
{
"_id" : ObjectId("57db79f8dbf8a742aa6bc85f"),
"name" : "First to MonogoDB",
"author" : "finley",
"tags" : "NoSQl"
}
],
"ok" : 1
}

unwind的目标字段必须为数组, 否则会产生错误:

exception: $unwind:  value at end of field path must be an array

$group

用于分组并进行统计:

db.user.aggregate(
{ $group:
{ _id: '$username', avg: {$avg: '$score'} }
}
)

结果:

"result" : [
{
"_id" : "forth",
"avg" : 95
},
{
"_id" : "third",
"avg" : 98
}
],
"ok" : 1
}

关系表达式中, _id键是必须的, 指定用于分组的属性, 属性值相同的文档将被分为一组.

其余键用于指定结果中属性的名称, 其值指定属性的值.

可以使用的集函数包括:

  • $avg

  • $sum

  • $max

  • $min

  • $first

  • $last

  • $push 将所选属性合并到一个array中

注意使用$加字段名组成的字符串来指定进行统计的属性.

索引

索引可以大幅提高查询数据的效率:

db.collection.ensureIndex(index, option)

index为一个词典, 其中键为属性名, 值为1或-1.1代表按升序建立索引, -1代表按降序建立索引.

索引可以建立在单一字段上, 或者在多个字段上建立复合索引.

option为指定可选参数的字典:

key type description default
background bool true: 建立索引时阻塞数据库, false: 后台建立 false
unique bool 索引字段是否唯一 false
dropDups bool 创建唯一索引时是否自动删除重复文档 false
name string 索引的名称 根据索引规则自动创建
sparse bool 对集合中不存在该字段的文档不创建索引, 使其无法被索引字段查询到 false
expireAfterSeconds integer 失效时间
v indexvision 索引版本号 自动
weights document 索引权重值
default_language string 对于文本索引, 决定词典规则和停用词 en

文档数据库MongoDB的更多相关文章

  1. 大数据技术原理与应用【第五讲】NoSQL数据库:5.6 文档数据库MongoDB

    文档数据库介于关系数据库和NoSql之间: 是最像关系数据库的一款产品,也是当前最热门的一款产品. 1.MongoDB简介:   1)     2)文档类型BSON(Binary JSON),结构类似 ...

  2. MongoDB学习1:认识文档数据库MongoDB

    1. 关于MongoDB 什么是MongoDB 一个以JSON为数据模型的文档数据库 为什么叫文档数据库 文档来自于"JSON Document",并非我们一般理解的pdf,wor ...

  3. 03丨认识文档数据库MongoDB

  4. 【翻译】MongoDB指南/引言

    [原文地址]https://docs.mongodb.com/manual/ 引言 MongoDB是一种开源文档型数据库,它具有高性能,高可用性,自动扩展性 1.文档数据库 MongoDB用一个文档来 ...

  5. 数据库:mongodb与关系型数据库相比的优缺点 (转)

    与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值 ...

  6. [转]mongodb与mysql相比的优缺点

    原文地址:http://blog.sina.com.cn/s/blog_966e430001019s8v.html 与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问 ...

  7. 数据库:mongodb与关系型数据库相比的优缺点

      与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精 ...

  8. (转)Mongodb相对于关系型数据库的优缺点

    与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值 ...

  9. MongoDB 与传统关系型数据库mysql比较

    与关系型数据库相比,MongoDB的优点: 转载自  http://blog.sina.com.cn/s/blog_966e430001019s8v.html①弱一致性(最终一致),更能保证用户的访问 ...

随机推荐

  1. UNIGUI上传文件

    UNIGUI上传文件 uniGUI提供了一个文件上传控件TUniFileUpload,进行数据的导入就变得比较容易.首先将TUniFileUpload控件放置在窗体上,按下导入按钮后,执行TUniFi ...

  2. MySQL--REPALCE INTO操作

    REPLACE INTO语法是MySQL数据库独特的扩展语法,可以提供“不存在即插入,存在即更新”的操作,MySQL官方文档解析其算法为: 1.尝试进行INSER 操作 2.如果INSERT 失败,则 ...

  3. ASP.NET MVC5 高级编程-学习日记-第二章 控制器

    2.1 控制器的角色 MVC模式中的控制器(Controller)主要负责响应用户的输入,冰球在响应时修改模型(Model).通过这种方式,MVC模式中的控制器主要关注的是应用程序流.输入数据的处理, ...

  4. sql server 字符串分割函数

    ),)) )) as begin ) set @SourceSql=@SourceSql+@StrSeprate while(@SourceSql<>'') begin )) insert ...

  5. ABP框架入门踩坑-配置数据库表前缀

    配置数据库表前缀 ABP踩坑记录-目录 本篇其实和ABP关系并不大,主要是EF Core的一些应用-.-. 起因 支持数据库表前缀应该是很多应用中比较常见的功能,而在ABP中并没直接提供这一功能,所以 ...

  6. [leetcode.com]算法题目 - Same Tree

    Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...

  7. centos下配置nginx遇到的一些基本的坑

    作为一个用.net的渣渣,常年混迹在window平台下,对Linux啥都不懂.随着.net core开源.跨平台后,也开始学习下linux. 在Desktop/Webs下放了一个index.html的 ...

  8. 关于Maven整合SSM项目中报错Invalid bound statement (not found):的问题解决

    如图:控制不报错 页面就是报500的错误 查阅了好多资料  都说是Mapper文件写的不对  我仔细找了好几遍也解决不了问题.. 解决: 坑爹的问题害我找了一上午原因,原来是需要在pom.xml文件中 ...

  9. Spring Boot log4j实现把日志存入mongodb

    准备工作 1.自定义appender的实现 log4j提供的输出器实现自Appender接口,要自定义appender输出到MongoDB,只需要继承AppenderSkeleton类,并实现几个方法 ...

  10. [vuejs] 终端npm run dev 不能自动打开浏览器运行项目解决办法

    终端执行: npm run dev 出现: I Your application is running here: http://localhost:8080 但并没有打开浏览器运行项目 解决办法: ...