https://pic.cnblogs.com/avatar/1285461/20190710101247.png

MongoDB基础

一、mac安装MongoDB

1.使用homebrew安装

  1. 安装homebrew
  2. 使用brew安装MongoDB

brew install mongodb

  1. 新建一个目录

mkdir data

  1. 命令行中指定数据库路径

mongod --dbpath="./data"

  1. 出现waiting for connections on port 27017就表示启动成功

2.下载安装包安装

  1. 去官网下载对应的版本

https://www.mongodb.com/download-center/community?jmp=nav

  1. 解压后放入/usr/local目录下
  2. 配置环境变量

export PATH=${PATH}:/usr/local/MongoDB/bin

  1. source .bash_profile使配置生效。输入mongod -version,回车后如果看到下面的版本号则说明MongoDB已经成功安装到了Mac上
  2. 新建data文件夹,再建db文件夹。

sudo mkdir -p /data/db

mongod启动命令参数

  • --port:指定服务端口号:默认为27017
  • --logpath:指定日志文件(不是目录)
  • --logappend:使用追加的方式写日志
  • --dbpath:指定数据库路径
  • --directoryperdb:设置每个数据库被保存在一个单独的目录
    启动客户端

mongo

二、MongoDB基本概念

  1. 数据库:MongoDB单个实例可以容纳多个数据库。

admin(权限) 要是将用户添加到这个数据库,这个用户自动继承所有数据库的权限。
local用于存储限于本地单台服务器的任意集合
config分片设置时,用于保存分片的相关信息。

  1. 集合:数据库由集合组成,类似于关系型数据库中的表
  2. 文档:集合组成文档,文档是一组键值对。

注:1.文档中的键值对是有序的。2.区分类型和大小写。3.文档不能有重复的键。

三、MongoDB常见的数据类型

数据类型 描述
String 字符串。在MongoDB中,UTF-8才是合法的
Integer 整型数值。可分为32位或64位
Boolean 布尔值
Double 双精度
Min/Max 将一根值与二进制JSON元素的最低值和最高值对比
Array 用于将数组或列表的多个值村委一个键
Timestamp 时间戳
Object 用于内嵌文档
Null 用于创建空值
Symbol 用于采用特殊符号类型的语言
Date 日期时间
Object ID 对戏ID
Binary Data 二进制数据
Code 文档中存储JavaScript代码
Regular expression 存储正则表达式

四、数据库操作

  1. 查看所有数据库:show dbs
  2. 选择数据库:use test

返回 switched to db test
注:当选择的数据库未创建,也可以切换过来,但是无法查到,需要在数据库中插入数据才算创建完毕。

  1. 查看当前数据库:dbdb.getName()
  2. 删除数据库:db.dropDatabase()

返回 {"dropped":"test","ok":1}

五、集合操作

  1. 查看集合帮助:db.test.help()
  2. 查看数据库下的集合:show collections
  3. 创建一个空集合:db.createCollection(collection_Name)

db.createCollection(movies)返回{"ok":1}

  1. 创建集合并插入一个文档:db.collection_Name.insert(movies)

db.douban.insert({name:'阿丽塔'}) 返回
WriteResult({ "nInserted" : 1 })

5.删除集合:db.Collection_name.drop()
5.创建一个有上限的集合:db.createCollection("name",{capped:true,size:10})
capped:默认值为false表示不设置上限,true表示设置上限

六、文档操作

1.插入文档

  1. insert

db.collection_name.insert(document)
注:每插入一个文档,默认会生成一个_id属性,用来作为文档的唯一标识,可以直接指定,但是如果集合中已经有了_id的话,会插入失败。

  1. save

db.collection_name.save(document)
注:不指定_id字段就类似于insert()方法,如果指定了则会更新该_id的数据。(存在则更新,不存在则添加)

2.更新文档

说明

db.collection.update(
    <query>,
    <updateObj>,
    {
    upsert:<boolean>,
    multi:<boolean>
    }
)
  • query(必选) 查询条件,指定要更新的文档所符合的条件
  • update(必选) 更新后的对象或指定一些更新操作符

$set直接指定更新后的值
$inc在原基础上累加

  • upsert(可选),如果不存在符合条件是否插入,默认false不插入
  • multi(可选),MongoDB默认只更新找到的第一条,设置为true,就更新所有符合条件的。必须和$操作符一起才有效。

简单例子:

update aritcle set title = "mongodb" where read > 100

db.article.update({"read"{"&gt":100}},{"$set":{"title":"mongodb"}})

操作符

  1. $inc:在原基础上累加

db.grade1.update({name:"tom"},{$inc:{age:10}}) //tom age 累加10

  1. $push:向数组中添加元素,不会覆盖已有的

db.grade1.update({name:"tom"},{$push:{"hobby":reading}})

  1. $addToSet:给数组添加或设置一个值

db.grade1.update({_id:3},{$addToSet:{friends:'huge'}})

  1. $pop:删除数组的第一个或者最后一个元素

传入1删除最后一个,-1删除第一个
db.grade1.update({_id:3},{$pop:{friends:1}})

  1. $each:在$addToSet中使用时,若有则忽略,若没有则添加。在$push中使用时,不管有没有都会添加。
  2. $ne:不等于

db.grade1.update({hobby:{$ne:"reading"}},{$push:{hobby:"drinking"}})

  1. $set:设置字段的值

/*原来的数据*/:
{_id:3, info:{id: '11'}, friends:['liudehua', 'zhourunfa']}

/*设置字段第一层的值*/
db.grade1.update({_id:3},{$set:{"info11":{id:"11"}}})

/*设置嵌套字段的值*/
db.grade1.update({_id:3}, {$set:{"info.id":'22'}})

/*修改指定索引元素*/
db.grade1.update({_id:3}, {$set:{"friends.1":'zhangmanyu'}})
  1. $unset:删除指定的键

db.grade1.update({name:tom},{$unset:{"age":""}})

3.删除文档

db.collection.remove(
    <query>,
    {
      justOne:<boolean>
    }
)
  • query:(可选)删除文档的条件
  • justOne:(可选)设为true或1,则只删除匹配到的多个文档中的第一个。默认为false删除全部

db.grade1.remove({"name":"tom"},{justOne:treu})
db.grade1.remove({"name":"tom"}) //删除全部匹配的文档

4.查询文档

  1. find()

db.collection_name.find(query,projection);
query:过滤器,条件
projection:指定匹配返回哪些键

/projection/
{ field1: , field2: ... }
1 or true: 在返回的文档中包含这个字段
0 or false:在返回的文档中排除这个字段
注:_id字段默认一直返回,除非手动将_id字段设置为0或false

db.grade1.find() //查询grade1下的所有文档
select * from grade1

db.grade1.find({},{"name":1,"age":1})
  1. findOne()

只返回匹配到的第一条文档

3.方法pretty():将结果格式化

db.集合名称.find({条件文档}).pretty()

查询操作符

  1. $in:在数组范围内
db.grade1.find({age:{$in:[9,11]}})
select * from grade1 where age in(9,11)
  1. $nin:不在数组范围内
  2. $not:取反,为元语句,可以用在任何条件之上
    4.$gt:大于
    5.$gte:大于等于
    6.$lt:小于
    7.$lte:小于等于
    8.$ne:不等于

数组查询

原始数据

{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }

db.grade1.find({"friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ]}) //只能查到一条
db.grade1.find({"friends" : [ "Lily" ]}) //返回空
db.grade1.find({"friends" :{$all: ["Lily","Zhang San"]}}) //$all 多个元素同时存在才能匹配成功
db.grade1.find({"friends" :{$in: ["Zhang San"]}}) //$in 范围查询
db.grade1.find({"friends" :{$size:4}}) //限制数组长度,只有为4才匹配
db.collection.find( { field: value }, { array: {$slice: count } } ); //当$slice的参数是一个时,表示返回的数量;当是一个数组时,第一个参数表示偏移量,第二个表示返回的数量。

通过_id查询

注:通过_id进行查询,需要加上ObjectId

db.grade1.find({_id: '5c91ed1bcc5f270bc6111d2c'}).count() //0
db.grate1.find(_id:ObjectId("5c91ed1bcc5f270bc6111d2c")).count()
//1

正则匹配

db.collection.find({key:/value/})

db.grade1.find({name:/^T/})

db.grade1.find({name:{$regex:"^zh"}})

and、or

and:

db.grade1.find({field1:value1,field2:value2})

or:

db.grade1.find($or:[{key1:value1},{key2,value2}])

and和or联用

db.grade1.find({age:9,$or:[{name:tom1},{age:11}]})

分页查询

1.limit:控制返回数量

db.collection_name.find().limit(number)

2.skip:略过指定数量的数据

db.collection_name.find().skip(number)

3.sort:排序,使用 1 和 -1 来指定排序的方式,1为升序排列,而-1用于降序排列。

4.distinct:去重

db.collection_name.distinct(‘去重字段’,{条件})

数据的备份与恢复

mongodump -h dbhost -d dbname -0 dbdirectory

-h:服务器地址,端口号
-d:需要备份的数据库名称
-o:备份的数据存放位置

mongorestore -h dbhost -d dbname --dir dbdirectory

-h:服务器地址,端口号
-d:需要恢复的数据库实例
--dir:备份数据所在位置

聚合aggregate

聚合是基于数据处理的聚合管道,每个文档通过一个由多个阶段组成的管道,可以对每个阶段的管道进行分组、过滤等操作。然后经过处理再输出相应的结果。

db.集合名称.aggregate({管道:{表达式}})

常用管道如下(有些前面已经介绍过):

  1. $group:将集合中的文档分组,可用于统计结果
  2. $match:过滤数据,只输出符合条件的文档
  3. $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
  4. $sort:将输入文档排序后输出
  5. $limit:限制聚合管道返回的文档数
  6. $skip:跳过指定的文档数,返回余下文档
  7. $unwind:将数组类型的字段进行拆分

常用表达式:(语法:表达式:$列名)

  1. $sum:计算总和,$sum:1表示以一倍计数
  2. $avg:计算平均值
  3. $min:获取最小值
  4. $max:获取最大值
  5. $push:在结果文档中插入值到一个数组中
  6. $first:更加排序获取第一个文档的数据
  7. $last:根据怕徐获取最后一个文档的数据

例子:

# 按性别分组的人数
db.stu.aggregate(
    {$group:{_id:"$gender",count:{$sum:1}}
)
# 按hometown进行分组,获取不同组的平均年龄
db.stu.aggregate(
    {$group:{_id:"$hometown",mean_age:{$avg:"$age"}}}
)
# 将集合中所有文档分为一组  _id为null
db.stu.aggregate(
    {$group:{_id:null,counter:{$sum:1}}}
)

注:分组依据放 _id 后面
取不同的字段需要使用$
取字典嵌套的字典中的值时用$_id.country
可以按多个建同时进行分组
使用$group统计整个文档

db.stu.aggregate(
    {$group:{_id:null,count:{$sum:1}}}
)

使用$project

db.stu.aggregate(
    {$group:{_id:"$gender",count:{$sum:1}},
    {$project:{gender:"$_id",count:1,_id:0}}
)
# 修改输入输出的值

使用$match

#年龄大于20的学生,男性、女性有多少人
db.stu.agregate(
    {$match:{age:{$gt:20}}},
    {$group:{_id:"$gender",count:{$sum}}},
    {$project:{_id:0,gender:$_id,count:1}}
)
# 上一步的结果作为下一步的输入

db.stu.aggregate(
    {$group:{_id:{country:$country,province:$province}}},
    {$group:{_id:{country:"$_id.country",province:"$_id.province"}}},
    {$project:{country:"$_id.country",province:"$_id.province",_id:0}}
)

$unwind的使用

# 先插入数据
db.t1.insert([
    {"_id":1,"item":"a","size":["s","m","l"]},
    {"_id":2,"item":"b","size":[]},
    {"_id":3,"item":"c","size":["m"]},
    {"_id":4,"item":"d"},
    {"_id":5,"item":"e","size":null}]
)
#使用$unwind将数组字段进行拆分
db.t1.aggregate({$unwind:"$size"}) //null 不显示
db.t1.aggregate( [
   { $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] ) //保留属性值为空的文档

索引

建立索引:

db.集合.ensureIndex({属性:1}),1表示升序,-1表示降序

例子:

# 先在集合中插入数据作为测试
for(i=1;i<1000000;i++){db.t1.insert({name:"test"+i,age:i})}

# 查询性能分析
db.t1.find({name:"test100000"}).explain("executionStats")

# 建立索引
db.t1.ensureIndex({name:1})
# 默认_id为索引,上面语句会新建一个索引。再次查询会发现查询速度变快了

# 查看当前集合的所有索引
db.t1.getIndexes()

# 删除索引
db.t1.dropIndex("索引名称":1)

# 创建唯一索引
# 根据关键字段建立 唯一索引,可以对数据进行去重
db.t1.ensureIndex({name:1},{unique:true})

# 建立联合索引
db.t1.ensureIndex({name:1,age:1})

爬虫数据去重(增量式爬虫):

  1. 根据url地址进行去重(url地址唯一,对应的数据不会改变)

判断url地址是否在redis的集合中,存在就是请求过,不再请求
不存在,请求并将url存入redis集合中。

  1. 根据数据本身进行去重

选择特定的字段,使用加密算法(md5,sha1)将字段进行加密,生成字符串
新的数据进行相同的加密,如果相同,则看情况更新。不存在,直接插入。

布隆过滤器:

使用多个加密算法加密url地址,得到多个值。
将对应值的位置设置为1
新的url地址通过算法也生成多个值
如果对应位置全为1,说明被抓过,否则就将对应位置值设为1

详细的请参考:
布隆过滤器1
布隆过滤器2

参考:
https://www.runoob.com/mongodb/mongodb-remove.html
http://ghmagical.com/article/page/id/Bj7qgmJ3CJUE

posted @ 2019-07-29 19:18  学一点也是好  阅读(295)  评论(1编辑  收藏  举报