文档数据库MongoDB
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: [
{'<': upper},
{'&ne', bidden}
]
}
})
$type
用于根据BSON中的数据类型进行筛选:
find({attr:{$type:1}})
上面的查询限定了attr
的类型为double.
数字与类型之间的对照见下表:
Double
String
Object
Array
Binary Data
Undefined (已废弃)
ObjectId
Boolean
Date
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的更多相关文章
- 大数据技术原理与应用【第五讲】NoSQL数据库:5.6 文档数据库MongoDB
文档数据库介于关系数据库和NoSql之间: 是最像关系数据库的一款产品,也是当前最热门的一款产品. 1.MongoDB简介: 1) 2)文档类型BSON(Binary JSON),结构类似 ...
- MongoDB学习1:认识文档数据库MongoDB
1. 关于MongoDB 什么是MongoDB 一个以JSON为数据模型的文档数据库 为什么叫文档数据库 文档来自于"JSON Document",并非我们一般理解的pdf,wor ...
- 03丨认识文档数据库MongoDB
- 【翻译】MongoDB指南/引言
[原文地址]https://docs.mongodb.com/manual/ 引言 MongoDB是一种开源文档型数据库,它具有高性能,高可用性,自动扩展性 1.文档数据库 MongoDB用一个文档来 ...
- 数据库:mongodb与关系型数据库相比的优缺点 (转)
与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值 ...
- [转]mongodb与mysql相比的优缺点
原文地址:http://blog.sina.com.cn/s/blog_966e430001019s8v.html 与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问 ...
- 数据库:mongodb与关系型数据库相比的优缺点
与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精 ...
- (转)Mongodb相对于关系型数据库的优缺点
与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值 ...
- MongoDB 与传统关系型数据库mysql比较
与关系型数据库相比,MongoDB的优点: 转载自 http://blog.sina.com.cn/s/blog_966e430001019s8v.html①弱一致性(最终一致),更能保证用户的访问 ...
随机推荐
- UNIGUI上传文件
UNIGUI上传文件 uniGUI提供了一个文件上传控件TUniFileUpload,进行数据的导入就变得比较容易.首先将TUniFileUpload控件放置在窗体上,按下导入按钮后,执行TUniFi ...
- MySQL--REPALCE INTO操作
REPLACE INTO语法是MySQL数据库独特的扩展语法,可以提供“不存在即插入,存在即更新”的操作,MySQL官方文档解析其算法为: 1.尝试进行INSER 操作 2.如果INSERT 失败,则 ...
- ASP.NET MVC5 高级编程-学习日记-第二章 控制器
2.1 控制器的角色 MVC模式中的控制器(Controller)主要负责响应用户的输入,冰球在响应时修改模型(Model).通过这种方式,MVC模式中的控制器主要关注的是应用程序流.输入数据的处理, ...
- sql server 字符串分割函数
),)) )) as begin ) set @SourceSql=@SourceSql+@StrSeprate while(@SourceSql<>'') begin )) insert ...
- ABP框架入门踩坑-配置数据库表前缀
配置数据库表前缀 ABP踩坑记录-目录 本篇其实和ABP关系并不大,主要是EF Core的一些应用-.-. 起因 支持数据库表前缀应该是很多应用中比较常见的功能,而在ABP中并没直接提供这一功能,所以 ...
- [leetcode.com]算法题目 - Same Tree
Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...
- centos下配置nginx遇到的一些基本的坑
作为一个用.net的渣渣,常年混迹在window平台下,对Linux啥都不懂.随着.net core开源.跨平台后,也开始学习下linux. 在Desktop/Webs下放了一个index.html的 ...
- 关于Maven整合SSM项目中报错Invalid bound statement (not found):的问题解决
如图:控制不报错 页面就是报500的错误 查阅了好多资料 都说是Mapper文件写的不对 我仔细找了好几遍也解决不了问题.. 解决: 坑爹的问题害我找了一上午原因,原来是需要在pom.xml文件中 ...
- Spring Boot log4j实现把日志存入mongodb
准备工作 1.自定义appender的实现 log4j提供的输出器实现自Appender接口,要自定义appender输出到MongoDB,只需要继承AppenderSkeleton类,并实现几个方法 ...
- [vuejs] 终端npm run dev 不能自动打开浏览器运行项目解决办法
终端执行: npm run dev 出现: I Your application is running here: http://localhost:8080 但并没有打开浏览器运行项目 解决办法: ...