文档数据库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①弱一致性(最终一致),更能保证用户的访问 ...
随机推荐
- 将一个浮点数转换成人民币读法字符串(java)
public class Num2Rmb { private String[] hanArr = {"零" , "壹" , "贰&qu ...
- DOS和批处理基本命令
http://www.cnblogs.com/leizhao/archive/2013/03/07/2949026.html 1.rem和:: rem注释命令,该命令后的内容不被执行,但能回显 ::注 ...
- Oracle开发包被锁解决办法-终极办法
http://www.itpub.net/forum.php?mod=viewthread&tid=1761963 以前在数据库维护中,基本都是碰到表被锁的情况,然后就是查找被锁的表相关的信息 ...
- unigui 设置单元格颜色
procedure TF_Resource2.UniDBGrid1DrawColumnCell(Sender: TObject; ACol, ARow: Integer; Column: TUniD ...
- node-webkit学习(2)基本结构和配置
node-webkit学习(2)基本结构和配置 文/玄魂 目录 node webkit学习(2)基本结构和配置 前言 2.1 基本程序结构 2.2 package.json 2.2.1 必须的配置 ...
- 利用gotty在web浏览器模拟终端登录
1.随机url,9000端口访问 gotty -p " -r -w bash -i 2.简单用户名密码授权,9090端口访问 gotty -p -c user:password -w bas ...
- JS学习笔记3_函数表达式
1.函数表达式与函数声明的区别 函数声明有“提升”(hoisting)的特性,而函数表达式没有.也就是说,函数声明会在加载代码时被预先加载到context中,而函数表达式只有在执行表达式语句时才会被加 ...
- 【BZOJ5188】 [Usaco2018 Jan]MooTube
BZOJ5188 [Usaco2018 Jan]MooTube 突然发现BZOJ没有题目,放题面. 题意翻译 题面描述 在业余时间,Farmer John创建了一个新的视频共享服务,他将其命名为Moo ...
- C#导出HTML到PDF组件 Pechkin
C#导出PDF功能是开发中经常遇到的功能,我们采用第三方的组件,比如 iTextSharp, aspose等,还能搜到一些开源的类库, 但是对于一些内容复杂样式丰富的PDF,我们希望通过传入一个URL ...
- input输入框添加内部图标
有可能在制作网页的过程中遇到各种美化表单设计,这次我们来试着做一个demo 将input输入框添加内部图标 话不多说,看一下最终效果 我们的思路是,在一个div中,加入一个div和一个input标签, ...