zoukankan      html  css  js  c++  java
  • MongoDB_综合

    Mongodb

    一、mongodb的介绍

    mongodb的优势

    • 易扩展:NoSQL数据库种类繁多,但是一个共同的特定就是去掉关系数据库的关系型特性。数据之间无关系,这样非常容易扩展
    • 大数据,高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀,这得益于它的无关系型,数据库的结构简单
    • 灵活的数据模型:NoSQL无需事先为要存储的数据建立字段。随时可以存储自定义的数据格式,而在关系数据库里。增删字段是一件非常麻烦的事,如果是非常大数据量的表,增加字段简直就是一个噩梦

    二、mongodb安装

    • 下载安装包并上传到服务器上
    • 解压安装包
    • 移动到/usr/local/目录下
    • 将可执行文件添加到PATH路径中
    # 添加环境变量
    	vim .bashrc
    	export PATH=/usr/local/mongodb/bin:$PATH    
    # 使环境变量生效
    	source .bashrc
    
    • mongodb的相关启动,停止,重启,端口查看
    # 启动
    	systemctl start mangodb
    # 停止
    	systemctl stop mangodb
    # 重启
    	systemctl restart mangodb
    # 查看是否启动成功
    	ps -aux |grep mangodb
    # 默认端口
    	27017
    

    三、mongodb基本操作

    关于database的基础命令

    # 查看当前的数据库:
    	db
    # 查看所有的数据库:
    	show dbs /show databases
    # 切换数据库:
    	use db_name
    # 删除当前的数据库:
    	db.dropDatabase()
    

    关于集合的基础命令

    # 不手动创建集合:
    	向不存在的集合中第一次加入数据时,集合会被创建出来
    # 手动创建集合:
    	db.createCollection(name,options)
        db.createCollection("stu")
        db.createCollection("sub",{capped:true,size:10})
        参数capped:默认值为false表示不设置上限,值为true表示设置上限
        参数size:当capped值为true时,需要指定此参数,表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节。
    # 查看集合:
    	show collections
    # 删除集合:
    	db.集合名称.drop()
    

    数据类型

    Object ID:文档ID
    string: 字符串,最常用,必须是有效的UTF-8
    Boolean:存储一个布尔值,true或false
    Integer:整数可以是32位或者64位,这取决于服务器
    Double:存储浮点值
    Arrays:数组或列表,多个值存储到一个键
    Object:用于嵌入式的文档,即一个值为一个文档
    Null:存储Null值
    Timestamp:时间戳,表示从1970-1-1到现在的总秒数
    Date:存储当前日期或时间的UNIX时间格式
    

    注意点

    • 创建日期语句如下:参数的格式为YYY-MM-DD

      new Date('2020-1-1')

    • 每个文档都有一个属性,为id,保证每个文档的唯一性

    • 可以自己去设置 _id 插入文档,如果没有提供,那么Mangodb为每个文档提供了一个独特 _id,类型为objectID

    • objectID是一个12字符的十六进制数:

      • 前4个字节为当前时间戳
      • 接下来3个字节的机器ID
      • 接下来的2个字节中MongoDB的服务进程id
      • 最后3个字节是简单的增量值

    插入

    • db.集合名称.insert(document)
      • db.stu.insert({name:'gj',gender:1})
      • db.stu.insert({_id:"20200101",name:'gj',gender:1})
    • 插入文档时,如果不指定 _id参数,MongoDB会为文档分配一个唯一的Objectid

    四、mongodb数据查询

    mongodb插入数据

    • db.collecion.insert({}) 插入数据,_id存在就报错
    • db.collection.save({}) 插入数据,_id存在会更新

    mongodb的更新操作

    • db.test1000.update({name:"xiaowang"},{name:"xiaozhao"})
    • 把name为xiaowang的数据替换为{name:"xiaozhao"}
    • db.test1000.update({name:"xiaohong"},{$set:{name:"xiaozhang"}})
    • 把name为xiaowang的数据name的值更新为xiaozhang
    • db.test1000.update({name:"xiaozhang"},{$set:{name:"xiaohong"}},{multi:true})
    • {multi:true}达到更新多条的目的

    mongodb删除

    • db.test1000.remove({name:"xiaohong"},{justOne:true})
    • 默认情况会删除所有满足条件的数据,{justOne:true}能达到只删除一条的效果

    mongodb的count方法

    • db.collection.find({条件}).count()
    • db.collection.count({})

    mongodb的投影

    • 投影:选择返回结果的字段
    • db.collection.find({条件},{name:1,_id:0})
      • 1._id默认会显示,置为0不显示
      • 2.出了_id之外的其他字段,如果不显示,不写,不能写为0

    $group的注意点

    • $group对应的字典中有几个键,结果中就有几个键
    • 分组依据需要放到_id后面
    • 取不同的字段的值需要使用$,$gender,$age
    • 取字典嵌套的字典中的值的时候$_id.country
    • 能够同时按照多个键进行分组{$group:{_id:{country:"$country",province:"$province"}}}
      • 结果是:{_id:{country:"",province:""}

    编辑器写mongodb语句

    db.stu.find(
      {$or:[{age:{$gte:20}},{hometown:{$in:["桃花岛","华⼭"]}}]}
      )
    
    #按照gender进行分组,获取不同组数据的个数和平均年龄
    db.stu.aggregate(
      {$group:{_id:"$gender",count:{$sum:1},avg_age:{$avg:"$age"}}},
      {$project:{gender:"$_id",count:1,avg_age:"$avg_age",_id:0}}
      )
    # 按照hometown进行分组,获取不同组的平均年龄
    db.stu.aggregate(
      {$group:{_id:"$hometown",mean_age:{$avg:"$age"}}}
      )
    #使用$group统计整个文档
    db.stu.aggregate(
      {$group:{_id:null,count:{$sum:1},mean_age:{$avg:"$age"}}}
      )
    #选择年龄大于20的学生,观察男性和女性有多少人
    db.stu.aggregate(
      {$match:{$or:[{age:{$gt:20}},{hometown:{$in:["蒙古","⼤理"]}}]}},
      {$group:{_id:"$gender",count:{$sum:1}}},
      {$project:{_id:0,gender:"$_id",count:1}}
      )
    
    #page37页练习
    db.tv3.aggregate(
      {$group:{_id:{country:"$country",province:"$province",userid:"$userid"}}},
      {$group:{_id:{country:"$_id.country",province:"$_id.province"},count:{$sum:1}}},
      {$project:{country:"$_id.country",province:"$_id.province",count:1,_id:0}}
      )
    

    数据查询

    • 方法find():查询
      • db.集合名称.find({条件文档})
    • 方法findOne():查询,只返回第一个
      • db.集合名称.findOne({条件文档})
    • 方法pretty():将结果格式化
      • db.集合名称.find({条件文档}).pretty()

    比较运算符

    • 等于:默认是等于判断,没有运算符
    • 小于:$lt (less than)
    • 小于等于:$lte (less than equal)
    • 大于:$gt (greater than)
    • 大于不等于:$gte
    • 不等于:$ne

    db.stu.find({age:{gte:18}})

    范围运算符

    使用"$in","$nin"判断是否在某个范围内

    查询年龄为18、28的学生

    db.stu.find({age:{$in[18,28,38]}})

    逻辑运算符

    • and :在json中写多个条件即可

      查询年龄大于或等于18,并且性别为true的学生

      db.stu.find({age:{$gte18},genter:true})

    • or:使用$or,值为数组,数组中每个元素为json

      查询年龄大于18,或性别为false的学生

      db.stu.find({$or:[{age:{$gt:18}},{gender:false}]})

    • 查询年龄大于18或性别为男生并且姓名是郭靖

      db.stu.find({$or:[{age:{$gt:18}},{gender:false}],name:'gj'})

    使用正则表达式

    使用//或$regex编写正则表达式

    查询姓黄的学生

    db.products.find({sku:/^abc/})

    limit和skip

    • 方法:limit():用于读取指定数量的文档

      db.集合名称.find().limit(number)

      查询2条学生信息

      db.stu.find().limit(2)

    • 方法skip():用于跳过指定数量的文档

      db.集合名称.find().skip(number)

      db.stu.find().skip(2)

    • 同时使用

      db.stu.find().limit(2).skip(3)

    自定义查询

    使用$where 后面写一个函数,返回满足条件的数据
    查询年龄大于30的学生
    db.stu.find({
        $where:finction(){
            return this.age>30
        }
    })
    

    投影

    在查询的返回结果中,只选择必要的字段
    db.集合名称.find({},{字段名称:1,....})
    

    排序

    方法sort(),用于对集合进行排序

    db.集合名称.find().sort({字段:1,....})

    • 参数1 为升序排列
    • 参数2 为降序排列

    统计个数

    方法count()用于统计结果集中文档条数

    五、mongodb聚合

    聚合 aggregate

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

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

    常用管道

    在mangodb中,文档处理完毕后,通过管道进行下一次处理

    常用管道如下:

    • $group: 将集合中的文档分组,可用于统计结果

    • group bu null:将集合中所有文档分为一组

    • $match: 过滤数据,只输出符合条件的文档

    • $project: 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

    • $sort: 将输入文档排序后输出

    • $limit: 限制聚合管道返回的文档数

    • $skip: 跳过指定数量的文档,并返回余下的文档

    • $unwind: 将数组类型的字段进行拆分,将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值

    表达式

    处理输入文档并输出

    语法:表达式:'$列名'

    常用表达式:

    • $sum: 计算总和,$sun:1表示以一倍技数
    • $avg: 计算平均值
    • $min: 获取最小值
    • $max: 获取最大值
    • $push: 在结果文档中插入值到一个数组中
    • $first: 根据资源文档的排序获取第一个文档数据
    • $last: 根据资源文档的排序获取最后一个文档数据

    六、备份、恢复、索引

    备份

    备份的语法:
    	mongodump -h dbhost -d dbname -o dbdirectory
    -h:服务器地址,也可以指定端口号
    -d:需要备份的数据库名称
    -o:备份的数据存放的位置,此目录中存放着备份出来的数据
        
    

    恢复

    恢复语法:
    	mongorestore -h dnhost -d dbname --dir dbdirectory
    -h:服务器地址
    -d:需要恢复的数据库实例
    --dir:备份数据所在位置
    

    索引

    以提升查询速度

    mongodb mysql redis的区别和使用场景

    • mysql是关系型数据库,支持事物
    • mongodb,redis非关系型数据库,不支持事物
    • mysql,mongodb,redis的使用根据如何方便进行选择
      • 希望速度快的时候,选择mongodb或者是redis
      • 数据量过大的时候,选择频繁使用的数据存入redis,其他的存入mongodb
      • mongodb不用提前建表建数据库,使用方便,字段数量不确定的时候使用mongodb
      • 后续需要用到数据之间的关系,此时考虑mysql

    爬虫数据去重,实现增量式爬虫

    • 使用数据库建立关键字段(一个或者多个)建立索引进行去重

    • 根据url地址进行去重

      • 使用场景:
        • url地址对应的数据不会变的情况,url地址能够唯一判别一个条数据的情况
      • 思路
        • url存在redis中
        • 拿到url地址,判断url在redis的url的集合中是够存在
        • 存在:说明url已经被请求过,不再请求
        • 不存在:url地址没有被请求过,请求,把该url存入redis的集合中
      • 布隆过滤器
        • 使用多个加密算法加密url地址,得到多个值
        • 往对应值的位置把结果设置为1
        • 新来一个url地址,一样通过加密算法生成多个值
        • 如果对应位置的值全为1,说明这个url地址已经抓过
        • 否则没有抓过,就把对应位置的值设置为1
    • 根据数据本省进行去重

      • 选择特定的字段,使用加密算法(md5,sha1)讲字段进行假面,生成字符串,存入redis的集合中
      • 后续新来一条数据,同样的方法进行加密,如果得到的字符串在redis中存在,说明数据存在,对数据进行更新,否则说明数据不存在,直接插入
    坚持这种真诚,那么总归能遇到良人。
  • 相关阅读:
    洛谷 P1494 [国家集训队]小Z的袜子 /【模板】莫队
    洛谷 P2801 教主的魔法
    数据库三范式
    vi和vim三种常见模式
    linux目录结构的具体介绍
    Linux怎么用root用户登录
    虚拟机的网络连接的三种方式
    事务
    数据库存储引擎
    delete和truncate
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/12313648.html
Copyright © 2011-2022 走看看