mongodb使用
一、安装
安装看看这位老哥的 安装与配置
(我不是懒的写= - =)
二、语法
Object ID:文档ID
String:字符串, 最常用, 必须是有效的UTF- 8
Boolean:存储一 个布尔值,true或false
Integer:整数可以是32位或64位,这取决于服务器
Double:存储浮 点值
Arrays:数组或列表,多 个值存储到一个键
Object:用于嵌入式的文档,即一 个值为-一个文档
Null:存储Null值
Timestamp:时间戳, 表示从1970-1-1到现在的总秒数
Date:存储当前日期或时间的UNIX时间格式
注意点
-
创建日期语句如下:参数的格式为YYYY-MM-DD
new Date(‘2017-12- -20’) -
每个文档都有一个属性,为_id,保证每个文档的唯- -性
可以自己去设置_ id插入文档,如果没有提供,那么MongoDB为每个
文档提供了一个独特的_ id,类 型为objectID -
objectID是一个12字节的十六进制数: .
前4个字节为当前时间戳
接下来3个字节的机器ID
接下来的2个字节中MongoDB的服务进程id
最后3个字节是简单的增量值
mongodb中当你使用一个库,或者集合时,db就指代当前所在库,或者集合
db
显示当前所在库或者集合
1.数据库的创建、查看、删除
1.创建或使用数据库
use DATABASE_NAME
//如果数据库不存在,则创建数据库,否则切换到指定数据库。
2.查看所有数据库
show dbs
show databases
3.删除数据库
db.dropDatabase()
2.创建集合(类似表的概念)
db.createCollection(name, options)
//在mongodb中当你插入数据时,如果集合不存在么,就会自动创建集合
//查看集合
show collections 或 show tables
参数说明:
-
name: 要创建的集合名称
-
options: 可选参数, 指定有关内存大小及索引的选项
capped :?Boolean 创建固定大小的集合
autoIndexId:?Boolean 自动创建索引
size:number 指定大小,capped为true时
max:?number 指定文档的最大数量
在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段
3. 删除集合
db.collection.drop()
说明:
collection 为要删除的集合名
返回 Boolean
4. 插入数据
MongoDB 使用 insert() 或 save() 方法向集合中插入数据
///在mongodb中当你插入数据时,如果集合不存在么,就会自动创建集合
//插入的文档的_id已经存在会报错
db.COLLECTION_NAME.insert(document)
//如果插入的文档的_id已经存在则修改,不存在就添加
db.COLLECTION_NAME.save(document)
参数说明:
document:插入的json数据
5. 修改数据
db.collection.update(
<query>,
<update>,
{
upsert: ?<boolean>,
multi: ?<boolean>,
writeConcern: ?<document>
}
)
参数说明:
-
query : update的查询条件,类似sql update查询内where后面的。
-
update : update的对象和一些更新的操作符(如 inc…)等,也可以理解为sql update查询内set后面的
-
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
-
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。(multi只能和$operators,一起使用才有效)
-
writeConcern :可选,抛出异常的级别。
覆盖式修改(只能更新一条)
//users集合中存在一条数据{_id:1,name:"zhangsan",age:"16"} db.users.update({name:"zhangsan"},{name:"lisi"}) db.users.find() //会用update的对象直接替换,匹配到的数据,就发现,原本数据中age字段没有了 > {_id:1,name:'lisi'}
指定字段修改
db.users.update({name:"zhangsan"},{$set:{name:"lisi"}})//表示将name字段修改成lisi db.users.find() > {_id:1,name:"lisi",age:"16"}
修改所有匹配到的数据
db.users.update({name:"zhangsan"},{$set:{name:"lisi"}},{multi:true})
6. 删除数据
db.collection.remove(
?<query>,
{
justOne: ?<boolean>,
writeConcern: ?<document>
}
)
参数说明:
-
query :(可选)删除的文档的条件对象。
-
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
-
writeConcern :(可选)抛出异常的级别。
无匹配条件填默认删除所有
7. 查询数据
db.collection.find(?query, ?projection)
//pretty() 方法以格式化的方式来显示所有文档。
db.col.find().pretty()
//返回一条查询数据
findOne({})
参数说明:
-
query :可选,使用查询操作符指定查询条件
-
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
返回指定的字段(投影)
//需要返回的字段为1,不需要的不写,_id默认返回,不需要,需要加上_id:0 db.collection.find({},{name:1})
8. 多条件查询(and)
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
db.collection.find({key1:value1, key2:value2})
9. or查询
db.collection.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
)
10范围查询($in、nin)
满足指定条件查询
db.collection.find(key:{$in:[value1,value2,.....]})
11. 条件操作符(<、 =、 >)
条件操作符用于比较两个表达式并从mongoDB集合中获取数据。
MongoDB中条件操作符有:
-
(>) 大于 $gt (greater than)
-
获取 “col” 集合中 “likes” 大于 100 的数据
db.col.find({likes : {$gt : 100}}
类似于SQL语句:
Select * from col where likes > 100;
-
(<) 小于 $lt (less than)
-
想获取"col"集合中 “likes” 小于 150 的数据
db.col.find({likes : {$lt : 150}})
类似于SQL语句:
Select * from col where likes < 150;
-
(>=) 大于等于 $gte (greater than equal)
想获取"col"集合中 “likes” 大于等于 100 的数据
db.col.find({likes : {$gte : 100}})
类似于SQL语句:
Select * from col where likes >=100;
-
(<= ) 小于等于 $lte (less than equal)
-
获取"col"集合中 “likes” 小于 150 的数据
db.col.find({likes : {$lt : 150}})
类似于SQL语句:
Select * from col where likes < 150;
- (!= ) 不等于 $ne (not equal)
12.正则查询($regex、//)
//查询以abc开头的
db.col.find({key : {$regex :'^abc'}})
db.col.find({key : /^abc/})
13. $type操作符
$type操作符是基于BSON类型来检索集合中匹配的数据类型
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1 . |
Max key | 127 |
获取 “col” 集合中 title 为 String 的数据
db.col.find({"title" : {$type : 2}})
或
db.col.find({"title" : {$type : 'string'}})
14.自定义查询($where)
使用$where后面写一个函数,返回满足条件的数据
查询年龄大于30的学生
db.stu.find({
$where:function(){
return this.age>30;
}
})
15. 分页查询(limit 、skip)
当数据量大时,建议先skip再limit,效率更高
**limit()**方法
读取指定数量的数据记录
db.COLLECTION_NAME.find().limit(NUMBER)
参数说明:
NUMBER: number
**skip()**方法
跳过指定数量的数据
db.COLLECTION_NAME.find().skip(NUMBER)
跳过2条数据,查询2调数据
db.COLLECTION_NAME.find().skip(2).limit(2)
参数说明:
NUMBER: number
16.排序 (sort)
>db.COLLECTION_NAME.find().sort({KEY:1})
参数说明:
key: Number 1 为升序排列,而 -1 是用于降序排列。
17.统计数量(count)
返回本次查询的数据数量
db.COLLECTION_NAME.find().count()
//或者
db.COLLECTION_NAME.count(?option)
参数说明:
option: 查询条件,与find相同
18.去重(distinct)
对选择的字段进行去重,返回去重后的数组
db.COLLECTION_NAME.distinct('去重字段',{条件})
例子:
//users集合
{_id:1,name:'zhangsan',age:18}
{_id:2,name:'lisi',age:16}
{_id:3,name:'zhangsan',age:18}
{_id:4,name:'wangwu',age:20}
{_id:5,name:'wangwu',age:21}
//查询出users集合中name字段不重复的值
db.users.distinct('name')
> ['zhangsan','lisi','wangwu']
//查询出users集合中age打于18的name字段不重复的值
db.user.distinct("name",{"age":{$gt:18}})
>['wangwu']
三、聚合(aggregate)和管道
聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage) 组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
//db.集合名称.aggregate({管道:{表达式})
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
每个对象都会将处理后的数据流到下一个对象处理
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
示例数据:
//stu集合
db.stu.insert({"name":"张三","age":18,"class":"一班"})
db.stu.insert({"name":"李四","age":17,"class":"一班"})
db.stu.insert({"name":"小明","age":18,"class":"二班"})
db.stu.insert({"name":"小红","age":16,"class":"一班"})
db.stu.insert({"name":"李磊","age":20,"class":"二班"})
db.stu.insert({"name":"王二","age":21,"class":"一班"})
db.stu.insert({"name":"赵四","age":17,"class":"二班"})
db.stu.insert({"name":"张敏","age":18,"class":"一班"})
1. $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
//只显示name 和age,_id不显示需要填0
db.stu.aggregate({$match:{age:{$gt:18}}},{$project:{_id:0,name:1,age:1}})
{ "name" : "李磊", "age" : 20 }
{ "name" : "王二", "age" : 21 }
2.$match:用于过滤数据,只输出符合条件的文档。match使用MongoDB的标准查询操作。
//过滤出年龄大于18岁
db.stu.aggregate({$match:{age:{$gt:18}}})
>
{ "_id" : ObjectId("5ea679bb5046893a42e92837"), "name" : "李磊", "age" : 20, "cl
ass" : "二班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92838"), "name" : "王二", "age" : 21, "cl
ass" : "一班" }
3.$limit:用来限制MongoDB聚合管道返回的文档数。
db.stu.aggregate({$limit:2})
{ "_id" : ObjectId("5ea678f05046893a42e92833"), "name" : "张三", "age" : 18, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92834"), "name" : "李四", "age" : 17, "cl
ass" : "一班" }
4.$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
db.stu.aggregate({$skip:5})
{ "_id" : ObjectId("5ea679bb5046893a42e92838"), "name" : "王二", "age" : 21, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bc5046893a42e92839"), "name" : "赵四", "age" : 17, "cl
ass" : "二班" }
{ "_id" : ObjectId("5ea679bf5046893a42e9283a"), "name" : "张敏", "age" : 18, "cl
ass" : "一班" }
5.$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
//集合clothes
{"_id":1,"name":"衣服","price":5,size:["S","M","L"]}
{"_id":1,"name":"衣服","price":5,size:[]}
db.clothes.aggregate({$unwind:"$size"})
>//默认会清除指定字段为空的数据
{"_id":1,"name":"衣服","price":5,size:"S"}
{"_id":1,"name":"衣服","price":5,size:"M"}
{"_id":1,"name":"衣服","price":5,size:"L"}
db.clothes.aggregate({
$unwind:{
path:"$字段",
preserveNullAndEmptyArrays:<boolean> //防止数据丢失,默认false
}
})
6.$group:将集合中的文档分组,可用于统计结果。
db.stu.aggregate({$group:{"_id":"$分组的字段"}})
//以班级分组
db.stu.aggregate({$group:{"_id":"$class"}})
>{"_id":"一班"}
>{"_id":"二班"}
//按多条数据进行分组 _id中有几个键,就返回几个键 可以达到去重相同数据的目的
db.stu.aggregate({$group:{_id:{ class:"$class",name:"$name",age:"$age"}}})
{ "_id" : { "class" : "一班", "name" : "张敏", "age" : 18 } }
{ "_id" : { "class" : "二班", "name" : "赵四", "age" : 17 } }
{ "_id" : { "class" : "二班", "name" : "李磊", "age" : 20 } }
{ "_id" : { "class" : "一班", "name" : "小红", "age" : 16 } }
{ "_id" : { "class" : "一班", "name" : "王二", "age" : 21 } }
{ "_id" : { "class" : "一班", "name" : "李四", "age" : 17 } }
{ "_id" : { "class" : "二班", "name" : "小明", "age" : 18 } }
{ "_id" : { "class" : "一班", "name" : "张三", "age" : 18 } }
//嵌套字段管道操作
db.stu.aggregate({
$group:{_id:{ class:"$class",name:"$name",age:"$age"}, count:{$sum:1}}}
)
>
{ "_id" : { "class" : "一班", "name" : "张敏", "age" : 18 }, "count" : 1 }
{ "_id" : { "class" : "二班", "name" : "赵四", "age" : 17 }, "count" : 1 }
{ "_id" : { "class" : "二班", "name" : "李磊", "age" : 20 }, "count" : 1 }
{ "_id" : { "class" : "一班", "name" : "小红", "age" : 16 }, "count" : 1 }
{ "_id" : { "class" : "一班", "name" : "王二", "age" : 21 }, "count" : 1 }
{ "_id" : { "class" : "一班", "name" : "李四", "age" : 17 }, "count" : 1 }
{ "_id" : { "class" : "二班", "name" : "小明", "age" : 18 }, "count" : 1 }
{ "_id" : { "class" : "一班", "name" : "张三", "age" : 18 }, "count" : 1 }
//我们想让上面的数据输出就要从嵌套的——id中取值 {class:"一班","name":"赵四","age":18,"count":1}
db.stu.aggregate({
$group:{_id:{ class:"$class",name:"$name",age:"$age"}, count:{$sum:1}}
},
{$project:{_id:0,class:"$_id.class",name:"$_id.name",age:"$_id.age",count:1}}
)
>
{ "count" : 1, "class" : "一班", "name" : "张敏", "age" : 18 }
{ "count" : 1, "class" : "二班", "name" : "赵四", "age" : 17 }
{ "count" : 1, "class" : "二班", "name" : "李磊", "age" : 20 }
{ "count" : 1, "class" : "一班", "name" : "小红", "age" : 16 }
{ "count" : 1, "class" : "一班", "name" : "王二", "age" : 21 }
{ "count" : 1, "class" : "一班", "name" : "李四", "age" : 17 }
{ "count" : 1, "class" : "二班", "name" : "小明", "age" : 18 }
{ "count" : 1, "class" : "一班", "name" : "张三", "age" : 18 }
7.$sort:将输入文档排序后输出。
//按班级升序
db.stu.aggregate({$sort:{class:1}})
>
{ "_id" : ObjectId("5ea678f05046893a42e92833"), "name" : "张三", "age" : 18, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92834"), "name" : "李四", "age" : 17, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92836"), "name" : "小红", "age" : 16, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92838"), "name" : "王二", "age" : 21, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bf5046893a42e9283a"), "name" : "张敏", "age" : 18, "cl
ass" : "一班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92835"), "name" : "小明", "age" : 18, "cl
ass" : "二班" }
{ "_id" : ObjectId("5ea679bb5046893a42e92837"), "name" : "李磊", "age" : 20, "cl
ass" : "二班" }
{ "_id" : ObjectId("5ea679bc5046893a42e92839"), "name" : "赵四", "age" : 17, "cl
ass" : "二班" }
- $geoNear:输出接近某一地理位置的有序文档。
表达式
1.$sum:计算总和。
//分组后每组条数
db.stu.aggregate({$group:{"_id":"$class",count:{$sum:1}}})
{ "_id" : "二班", "count" : 3 }
{ "_id" : "一班", "count" : 5 }
2. $avg:计算平均值
//计算一班和二班的平均年龄
db.stu.aggregate({$group:{"_id":"$class",_age:{$avg:"$age"}}})
{ "_id" : "二班", "_age" : 18.333333333333332 }
{ "_id" : "一班", "_age" : 18 }
- $min:获取集合中所有文档对应值得最小值。
- $max:获取集合中所有文档对应值得最大值。
- $push:在结果文档中插入值到一个数组中。
- $addToSet: 在结果文档中插入值到一个数组中,但不创建副本。
- $first:根据资源文档的排序获取第一个文档数据。
- $last:根据资源文档的排序获取最后一个文档数据
四、数据的备份和恢复
本机是不需要-h的
1. 备份
mongodump -h dbhost -d dbname -o dbdirectory
-
-h:
MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-
-d:
需要备份的数据库名称,例如:test
-
-o:
备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
示例:
mongodump -h 127.0.0.1:27017 -d test -o ~/data/dump
2.恢复
mongorestore -h <hostname><:port> -d dbname <path> --dir dbdirectory
-
–host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
-
–db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
-
–drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
-
: mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。
你不能同时指定
和 --dir 选项,–dir也可以设置备份目录。 -
–dir:
指定备份的数据所在位置
你不能同时指定
和 --dir 选项。 示例:
mongorestore -h 127.0.0.1:27017 -d test --dir ~/data/dump/test
五、索引
mongodb中索引的类似mysql中的主建
提升查询速度
db.集合.ensureIndex({属性:1}),1为升序,-1为降序
测试插入10万条数据到数据库
for(i=0;i<100000;i++){
db.t255.insert({name:"test"+i,age:i})
}
//对比查询时间,这个是无索引
db.t255.find({name:'test10000'}).explain('executionStats')
查询结果对象中这个代表时间
//"executionTimeMillisEstimate" : 41,
//添加索引
db.t255.ensureIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1, 之前有一个索引 _id是默认的
"numIndexesAfter" : 2, 之后,创建了一个
"ok" : 1
}
再次执行查询
//"executionTimeMillisEstimate" : 0,
获取创建的索引
db.集合.getIndexes()
删除索引
db.集合.dropIndex('索引名称')
创建唯一索引(可以用于对爬虫数据的去重)
//默认情况下索引自动的值可以相同
创建唯一
db.集合.ensureIndex({"字段":1},{"unique":true})
联合索引
db.集合.ensureIndex({"字段":1,"字段1":1})
test --dir ~/data/dump/test
### 五、索引
mongodb中索引的类似mysql中的主建
提升查询速度
```js
db.集合.ensureIndex({属性:1}),1为升序,-1为降序
测试插入10万条数据到数据库
for(i=0;i<100000;i++){
db.t255.insert({name:"test"+i,age:i})
}
//对比查询时间,这个是无索引
db.t255.find({name:'test10000'}).explain('executionStats')
查询结果对象中这个代表时间
//"executionTimeMillisEstimate" : 41,
//添加索引
db.t255.ensureIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1, 之前有一个索引 _id是默认的
"numIndexesAfter" : 2, 之后,创建了一个
"ok" : 1
}
再次执行查询
//"executionTimeMillisEstimate" : 0,
获取创建的索引
db.集合.getIndexes()
删除索引
db.集合.dropIndex('索引名称')
创建唯一索引(可以用于对爬虫数据的去重)
//默认情况下索引自动的值可以相同
创建唯一
db.集合.ensureIndex({"字段":1},{"unique":true})
联合索引
db.集合.ensureIndex({"字段":1,"字段1":1})