zoukankan      html  css  js  c++  java
  • MongoDB安装和入门

    什么是MongoDB

    MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库。采用BSON存储文档数据。2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。MongoDB用c++编写的。

    优势:
    • 面向文档的存储:以 JSON 格式的文档保存数据。

    • 任何属性都可以建立索引。

    • 复制以及高可扩展性。

    • 自动分片。

    • 丰富的查询功能。

    • 快速的即时更新。

    • 来自 MongoDB 的专业支持。

    mongodb安装与启动

    mongodb下载网址: https://www.mongodb.com/download-center/community

    选择版本、系统环境、包 。以下将以tgz包 为例

    下载完成将得到mongodb-linux-x86_64-rhel70-4.2.8.tgz包,将其上传到linux(centos7)某个目录

    上传完成后解压

    tar zxvf mongodb-linux-x86_64-rhel70-4.2.8.tgz

    移动到/usr/local/mongodb目录(非必须)

    mv mongodb-linux-x86_64-rhel70-4.2.8/ /usr/local/mongodb

    创建专门的负责的用户并赋予权限(非必须)

    cd /usr/local/mongodb 
    groupadd mongodb
    useradd -s /sbin/nologin -g mongodb -M mongodb
    mkdir data log run
    chown -R mongodb:mongodb data log run

    在/usr/local/mongodb 里面创建一个配置文件 mongodb.conf

    vim mongodb.conf 并写入下面的信息:

    bind_ip=0.0.0.0
    port=27017
    dbpath=/usr/local/mongodb/data/
    logpath=/usr/local/mongodb/log/mongodb.log
    pidfilepath =/usr/local/mongodb/run/mongodb.pid
    logappend=true
    fork=true    
    maxConns=500
    noauth = true
    
    
    # 配置解释:
    # fork=true   运行在后台
    # logappend=true  如果为 true,当 mongod/mongos 重启后,将在现有日志的尾部继续添加日志。否则,将会备份当前日志文件,然后创建一个新的日志文件;默认为 false。
    # noauth = true  不需要验证用户密码
    # maxConns=500 最大同时连接数 默认2000

    以上是MongoDB的安装与启动的准备工作,可直接启动 启动命令:

    /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb.conf

    配置环境变量

    vim /etc/profile 

    在/etc/profile文件末尾添加一行:

    export PATH=/usr/local/mongodb/bin:$PATH

    让其生效:

    source /etc/profile

    查看当前mongodb的版本:

    mongod --version

    MongoDB的crud

    理解几个概念

    集合:对应mysql的table

    文档:对应mysql的一条数据

    数据库的操作

    连接MongoDB,执行mongo命令

    mongo

     查看MongoDB自带的原始数据库

    show dbs

     

    admin:从权限角度来看,这是“root”数据库。如果将一个用户添加到这个数据库。这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器

    local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合

    config:当mongo用于分片设置时,config数据库在内部使用。用于保存分片的相关信息

     

    创建或进入数据库:use 数据库名

    use test

    使用use时,如果数据库存在则会进入到相应的数据库,如果不存在则会自动创建  一旦进入数据库,则可以使用db来引用当前库 ;

    如果是第一次创建,那个这个数据库只是存在于内存当中,直到这个数据库中创建了集合后才会持久化到磁盘上

     

    删除数据库:db.dropDatabase()

    db.dropDatabase()

    集合的操作

     用于删除已经持久化的数据库,刚创建在内存中的数据库删除无效

    相当于恢复到刚创建test数据库且并没有持久化到磁盘的状态

    创建一个集合:db.createCollection("集合名称")

    db.createCollection("西游记")

    查看所有的集合show tables 或者 show collections

    show tables
    show collections

    删除集合:db.集合名称.drop()

    db.西游记.drop()

    文档的操作

    添加一条数据

    db.xyj.insert({name:"猪八戒",age:28,gender:""})

    这里会自动创建xyj这个集合

    查询数据

    db.xyj.find()

     可以看到,我们没有指定id,MongoDB自动给我们生成了一条id,我们也可以指定id,如下

    添加一条指定id的数据

    db.xyj.insertOne({_id:"workd",name:"猪八戒",age:28,gender:""})

     当我们向集合中插入文档时,如果没有给文档指定 _id属性,则数据库会自动为文档添加 _id该属性用来作为文档的唯一标识 _id

    我们可以自己指定,如果我们指定了数据库就不会在添加了,如果自己指定 _id 也必须确保它的唯一性

    批量添加数据

    db.xyj.insert([
    ...      {name:"沙和尚",age:38,gender:""},
    ...      {name:"白骨精",age:16,gender:""},
    ...      {name:"蜘蛛精",age:14,gender:""}
    ... ])

     或者以下命令也是一样的效果

    db.xyj.insertMany([
         {name:"沙和尚",age:38,gender:""},
         {name:"白骨精",age:16,gender:""},
         {name:"蜘蛛精",age:14,gender:""}
    ])

     总结:

      db.collection.insertOne() 插入一个文档对象
      db.collection.insertMany() 插入多个文档对象

    额外小知识

    try{
        db.xyj.insert([
          {name:"沙和尚",age:38,gender:""},
          {name:"白骨精",age:16,gender:""},
          {name:"蜘蛛精",age:14,gender:""}
        ]);
    }catch(e){
        print(e)
    }

    可以知道那条插入失败

    全量修改操作

    db.xyj.update({_id: ObjectId("5f0189a368c6a000f725c87b")},{age:NumberInt(30)})

     执行效果:这条数据只有age一个字段了

    局部修改操作

    db.xyj.update({_id:ObjectId("5f0189a368c6a000f725c87c")},{$set:{age:NumberInt(30)}})

     执行效果:只会修改这条数据的某个字段

    批量修改

    db.xyj.update({name:"蜘蛛精"},{$set:{age:NumberInt(100)}},{multi:true})

     注意:在修改条数据时,必须要加上第三个参数{multi:true},否则只会修改一条数据

    字段增加操作

    db.xyj.update({_id:"workd"},{$inc:{age:NumberInt(1)}})

     注意:$inc对应的字段必须是数字,而且递增或递减的值也必须是数字。

    删除文档

    db.xyj.remove({_id:"workd"})

    删除文档字段

    db.xyj.update({"_id": ObjectId("5f0189a368c6a000f725c87d")}, {"$unset": {"name":1}})

    $unset指定字段的值只需是任意合法值即可

    删除所有

    db.xyj.remove({})  

     

    数组操作

    插入测试数据

    db.xyj.insertMany([
         {name:"沙和尚",age:38,gender:"",hobby:["打篮球","吃喝"]},
         {name:"白骨精",age:16,gender:"",hobby:["吃喝"]},
         {name:"蜘蛛精",age:14,gender:"",hobby:["跑步","打乒乓球"]},
         {name:"唐生",age:25,gender:"",hobby:["坐禅","吃喝"]}
    ]);

    添加数组内容($push)

    db.xyj.update({"name": "白骨精"}, {"$push": {"hobby": "念佛"}})

     删除元素($pop

    删除最后一个元素

    db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d10")}, {"$pop": {"hobby": 1}})

    删除第一个元素

    db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d13")}, {"$pop": {"hobby": -1}})

     

    删除特定元素($pull

    db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d11")}, {"$pull": {"hobby": "念佛" }})

    添加一条测试数据

    db.xyj.insert({name:"猪八戒",age:28,gender:"",address: [{place: "nanji", tel: 123}, {place: "dongbei", tel: 321}]});

    更新嵌套数组的值($set)

    db.xyj.update({"_id": ObjectId("5f019881caf12a975c177d14")}, {"$set": {"address.0.tel": 213}})

     数组查询:

    db.xyj.find({"hobby":"跑步"})

    多个元素的查询

    db.xyj.find({"hobby":{"$all": ["跑步", "打乒乓球"]}})

    只有hobby数组同时存在跑步和打乒乓球才会匹配

    限制数组长度查询

    db.xyj.find({"hobby": {"$size": 1}})

    只有数组的长度是1才会匹配

    投影查询

    db.xyj.find({name:"白骨精"},{name:1,_id:0})

    1表示显示 0表示强制隐藏

    相当于sql里面只查某些字段

    按字段条件查询

    db.xyj.find({name:"白骨精"})

     按字段条件查询并只返回一条

    db.xyj.findOne({gender:""})

    其他api就不都演示了

    组合查询:

    语法:db.xyj.find($and:[{},{},{}])
    //查询年级大于20小于50的
    db.xyj.find({$and:[{age:{$gt:NumberInt(20)}},{age:{$lt:NumberInt(50)}}]})  
    //查询名字里有”精“的或者年纪大于30的
    db.xyj.find({$or:[{age:{$gt:NumberInt(30)}},{name:/精/}]})  

    比较查询:

    db.xyj.find({age:{$gt:NumberInt(20)}})  //查询年级大于20岁的
     
    $gt--》大于     $lt--》小于   $gte--》大于等于     $lte--》小于等于   $ne---》不等于(不等于不一定要用于数字)

    包含查询:

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

    不包含:

     db.xyj.find({age:{$nin:[28,38]}})

    Like:

    db.xyj.find({"name": /精/})

    统计查询:

    db.xyj.count()或者db.xyj.count({字段:条件})

    取模:

    db.xyj.find({"age": {$mod: [5, 1]}})
    比如我们要匹配 age % 5 == 1

    是否存在($exists)

    db.xyj.find({"love": {"$exists": true}})  // 如果存在字段love,就返回
    db.xyj.find({"love": {"$exists": false}}) // 如果不存在字段love,就返回

     

    分页查询

    limit:显示几条记录

    skip:跳过几条记录

    第一次查询:db.xyj.find().limit(2)

    第一次查询:db.xyj.find().limit(2).skip(2)

    结合排序:db.xyj.find().limit(2).skip(2).sort({age:1}) // 1代表升序,-1代表降序

    执行顺序: sort > skip > limit

     

    聚合管道

    较常见的管道操作符以及他们的作用:

    操作符描述语法
    $project 数据投影,主要用于重命名,增加,删除字段 db.article.aggregate({ $project : {title : 1 ,author : 1 ,}});
    $match 过滤,筛选符合条件的文档,作为下一阶段输入 db.articles.aggregate( [{ $match : { score : { $gt : 70, $lte : 90 } } },{ $group: { _id: null, count: { $sum: 1 } } }] );
    $limit 限制经过管道的文档数量 db.article.aggregate({ $limit : 5 });
    $skip 待操作集合处理前跳过部分文档 db.article.aggregate({ $skip : 5 });
    $unwind 将数组拆分成独立字段 db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$tags"})
    $group 对数据进行分组 db.article.aggregate({ $group : {_id : "$author",docsPerAuthor : { $sum : 1 },viewsPerAuthor : { $sum : "$pageViews" }}});
    $sort 对文档按照指定字段排序 db.users.aggregate( { $sort : { age : -1, posts: 1 } });
    $sample 随机选择从其输入指定数量的文档。 { $sample: { size: <positive integer> } }
    $out 必须为pipeline最后一个阶段管道,因为是将最后计算结果写入到指定的collection中  
    $indexStats 返回数据集合的每个索引的使用情况 { $indexStats: { } }

    插入测试数据

    document1=({name:'dogOne',age:1,tags:['animal','dog'],type:'dog',money:[{min:100},{norm:200},{big:300}]});
    
    document2=({name:'catOne',age:3,tags:['animal','cat'],type:'cat',money:[{min:50},{norm:100},{big:200}]});
    
    document3=({name:'catTwo',age:2,tags:['animal','cat'],type:'cat',money:[{min:20},{norm:50},{big:100}]});
    
    document4=({name:'dogTwo',age:5,tags:['animal','dog'],type:'dog',money:[{min:300},{norm:500},{big:700}]});
    
    document5=({name:'appleOne',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]});
    
    document6=({name:'appleTwo',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]});
    
    document7=({name:'pineapple',age:0,tags:['fruit','pineapple'],type:'pineapple',money:[{min:8},{norm:9},{big:10}]});
    
    db.mycol.insert(document1)
    
    db.mycol.insert(document2)
    
    db.mycol.insert(document3)
    
    db.mycol.insert(document4)
    
    db.mycol.insert(document5)
    
    db.mycol.insert(document6)
    
    db.mycol.insert(document7)

     假定我们想提取money中min为100的文档,并且只输出名称和money数组中的min那一项

    db.mycol.aggregate(
       {$match:{'money.min':100}},
       {$project:{_id:0,name:'$name',minprice:'$money.min'}}
    )

    假定我们想提取money中min小于100的文档,并且限制3个文档,跳过一个文档再显示

     通过type类型来对数据进行分类,并且同时统计他们的年龄age总和

    db.mycol.aggregate(
        {$group:{_id:'$type',sumage:{$sum:'$age'}}}
    )

     按照年龄对数据进行排序

    db.mycol.aggregate(
        {$group:{_id:'$type',sumage:{$sum:'$age'}}},
        {$sort:{sumage:1}}
    )

  • 相关阅读:
    jmeter压力测试
    反射【类Class、成员变量Field、方法Method】
    模块十 python标准库
    模块五 python常用数据结构
    模块四 python函数
    模块三 python控制流语法
    模块二 python基本数据类型与操作
    第四章后总结文档
    第六章节练习
    第五章节练习
  • 原文地址:https://www.cnblogs.com/lusaisai/p/13246880.html
Copyright © 2011-2022 走看看