zoukankan      html  css  js  c++  java
  • MongoDB

    1. 什么是MongoDB?

    MongoDB是一个开源NoSQL(NotOnly SQL)分布式数据库,不同于MySQL的关系型数据库。它所有的数据以文档(Binary JSON文档)的形式存储。没有表和行的概念。

    1. 基本概念

    数据库(database):一个Mongo实例对应多个数据库。

         Mongo中的数据库等同于MySql中的数据库。

    集合(collection): 数据库由集合组成。

        Mongo中的集合等同于MySql中的表(table)。

    文档(document):集合由文档组成。

       Mongo中的文档等同于MySql中的记录(row)。

    key: 文档由key-value组成。

       Mongo中的key相当于MySql中的列(field)。

    2. 优缺点

    优点:

    1) 高并发

    2)大数据量

    3)分布式(多台服务器)

    缺点:

    不可靠,会出现数据丢失

    3. ObjectId

    在MySql数据库中,id是自增ID。在MongoDB这种分布式数据库中,该方法不实用; 在该数据库中,使用12个字节字符串组成的ObjectId类型。

    • 4字节: UNIX时间戳
    • 3字节:运行MongoDB数据库的机器的MAC地址
    • 2字节:生成该Id的进程
    • 3字节:随机数

    2. MongoDB的安装

    1. windows系统

    下载安装包,解压,打开bin目录

    cd MongoDB/bin

    启动服务器端(默认断开27017)

    //  data是数据存放目录
    mongod --dbpath=./data

    mongod命令的其他参数:

    --port 指定端口号;默认端口是27017
    --logpath 指定日志文件;不是文件目录
    --logappend 使用追加的方式追加日志
    --dbpath 指定数据库路径
    --directoryperdb 设置每个数据库在单独的目录

    监听客户端请求

    mongo
    // 成功的标志是出现>

    2. MacOS系统

    安装教程

    brew tap mongodb/brew
    // $ brew install <formula>
    eg: brew install mongodb-community

    监听客户端请求

    mongo

    安装后的文件夹所在的目录

    /usr/local/Cellar/mongodb-community/

    3. MongoDB的命令

    查看mongoDB的所有命令:

    db.help();

    1. 操作数据库

    1. 创建数据库

    使用use,切换到对应的数据库。如果数据库不存在,则创建数据库

    use dbname;

    2. 查看数据库列表

    show dbs;

    3. 删除数据库

    先切换到数据库;再删除

    use dbname;
    db.dropDatabase();

    2. 操作集合

    1.创建集合

    切换到要操作的数据库,直接插入数据;会自动创建集合;其中stu是集合。

    use school;
    db.stu.insert({name: "lyra"});
    db.stu.insert({_id: 1, name: "lyra1"});

    2. 创建集合2

    db.createCollection('stu')

    3. 操作文档

    1. 插入文档

    插入多条数据

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    > db.stu.insert([{_id:2, age:2}, {_id: 3, age: 3}])
    BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
    })
    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 3 }

    2. 更新文档(整条内容替换)

    db.stu.save({_id: 1, name: "lyra1"});

    3. 查看集合下所有文档内容

    db.stu.find();

    查看指定的文档

    db.stu.find(<query>);

    4. 删除集合

    db.stu.drop();

    4. 更新文档

    • query:  查询条件; 如果是{}, 则表示更新所有的数据。
    • updateObj: 更新体
    • upsert: update/insert; 为true时表示,查询条件匹配则更新;不匹配则插入
    • multi: 为true时表示同时变更所有的数据
    db.collection.update(
    <query>,
    <updateObj>, {
    upsert: true, multi: true } }

    eg:

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee" }
    > db.stu.update({_id: 2}, {age: 1})
    WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
    > db.stu.update({_id: 2}, {age: 1}, {upsert: true})
    WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 2 })
    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee" }
    { "_id" : 2, "age" : 1 }

    5. 更新(update)操作符

    1. $set- 只修改指定字段,其他字段保持不变

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "age" : 1 }
    > db.stu.update({_id: 1}, {$set:{age: 18}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "age" : 18 }

    2. $inc-执行字段增加

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "age" : 18 }
    > db.stu.update({_id: 1}, {$inc:{age: 1}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "age" : 19 }

    3. $unset-删除指定字段

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "age" : 19 }
    > db.stu.update({_id: 1}, {$unset:{age: 1}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee" }

    4. $push-添加数组数据(数据数据可能会重复)

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee" }
    > db.stu.update({_id:1}, {$push:{hobbies:'swimming'}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
    > db.stu.update({_id:1}, {$push:{hobbies:'swimming'}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "swimming" ] }

    5. $ne-NotEqual限制数组的重复添加

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
    > db.stu.update({_id:1, hobbies:{$ne: 'swimming'}}, {$push:{hobbies:'swimming'}});
    WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }

    6.$addToSet-添加不重复数据的数组(集合)

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
    > db.stu.update({_id:1}, {$addToSet:{hobbies:'swimming'}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
    > db.stu.update({_id:1}, {$addToSet:{hobbies:'singing'}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "singing" ] }

    7. $pop-删除数组的最后一个数

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "singing" ] }
    > db.stu.update({_id:1}, {$pop:{hobbies:1}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    >
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }

    8.$each-合并数组元素

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
    > var arr = ['drinking', 'smoking'];
    > db.stu.update({_id:1}, {$addToSet:{hobbies:{$each: arr}}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "drinking", "smoking" ] }

    9. 修改指定索引的值

    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "drinking", "smoking" ] }
    > db.stu.update({_id:1}, {$set:{'hobbies.0': 'drawing'}});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stu.find({_id:1});
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }

    6. 删除文档

    基本语法:

    • collection_name 集合名称
    db.collection_name.remove(
       <query>,
       {
          justOne: <boolean>
       }
    )

    删除所有匹配条件的数据

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 2, "age" : 1 }
    > db.stu.remove({age: 1})
    WriteResult({ "nRemoved" : 1 })
    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }

    justOne只删除匹配条件的第一条数据

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 2 }
    > db.stu.remove({age:2}, {justOne: true})
    WriteResult({ "nRemoved" : 1 })
    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 3, "age" : 2 }

    7. 查询文档操作符

    1. find-查询出所有满足条件的数据(最多20条)

    基本语法

    • collection_name: 集合名称
    • query: 查询条件
    • key: 指定特定的列
    • 0: exclusion 不包含该列
    • 1: inclusion; 包含该列
    db.collection_name.find(
      <query>,
      {
         key: 0/1
      }
    )

    ⚠️: 0/1不能混用;即不能同时存在(_id除外)

    示例: 返回指定的列

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 3, "age" : 2 }
    > db.stu.find({_id:1}, {name:1, _id:0});
    { "name" : "lyraLee" }

    2. findone-查询出满足条件的第一条数据

    > db.stu.find();
    { "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
    { "_id" : 3, "age" : 2 }
    { "_id" : ObjectId("5e4ca86e925de31003f5cfbe"), "sex" : "female" }
    { "_id" : ObjectId("5e4ca885925de31003f5cfbf"), "sex" : "female" }
    > db.stu.findOne({sex: 'female'})
    { "_id" : ObjectId("5e4ca86e925de31003f5cfbe"), "sex" : "female" }

    3. $in- 包含

    > db.stu.find();
    { "_id" : 1, "age" : 1 }
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 3 }
    { "_id" : 4, "age" : 4 }
    { "_id" : 5, "age" : 5 }
    > db.stu.find({age: {$in: [2,4]}})
    { "_id" : 2, "age" : 2 }
    { "_id" : 4, "age" : 4 }

    4. $nin- 不包含

    > db.stu.find({age: {$nin: [2,4]}})
    { "_id" : 1, "age" : 1 }
    { "_id" : 3, "age" : 3 }
    { "_id" : 5, "age" : 5 }

    5. $gte - greater than Or equal

       $lte - less than Or equal

       $lt - less than

       $gt - greater than

    > db.stu.find({age: {$gte: 2, $lte: 4}})
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 3 }
    { "_id" : 4, "age" : 4 }

    6. $not - 取反

    > db.stu.find({age:{$not: {$gte: 2, $lte: 4}}})
    { "_id" : 1, "age" : 1 }
    { "_id" : 5, "age" : 5 }

    7. 查询数组

    • 包含数组中的某一个值
    > db.stu.find()
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
    { "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
    { "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    { "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }
    > db.stu.find({hobbies: 'A'})
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
    { "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    • $all-同时包含数组中的某些值
    > db.stu.find({hobbies: {$all: ['A','B']}})
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    • $in-包含其中任意一个值
    > db.stu.find({hobbies: {$in: ['A','B']}})
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
    { "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
    { "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    • $size-按数组长度查询
    > db.stu.find({hobbies: {$size:2}})
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    • $slice-返回数组的部分数据
    > db.stu.find({_id:1}, {hobbies: {$slice: 2}})
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B" ] }
    > db.stu.find({_id:1}, {hobbies: {$slice: -2}})
    { "_id" : 1, "age" : 1, "hobbies" : [ "B", "C" ] }

    8. $where-查询条件语句(查询速度慢)

    > db.stu.find({$where: "this.age>2 && this.age<4"})
    { "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }

    8. 查询方法

    1. cursor

    find()方法返回一个结果集(最多返回20条),可以通过其逐条查询

    - cursor.hasNext():返回布尔值

    - cursor.next(): 下一条数据

    - printjson(data): 打印数据 

    > var cursor = db.stu.find();
    > while(cursor.hasNext()) { printjson(cursor.next()); }
    { "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
    { "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
    { "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    { "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }

    2. count()

    返回结果集的条数

    > db.stu.count();
    30

    3. 正则表达式查询

    > db.stu.find({name: /^my/})
    { "_id" : 1, "name" : "mynameishehe" }

    4. 逻辑与或(and/or)

    -and

    > db.stu.find({age: {$gte: 2, $lte: 4}})
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 3 }
    { "_id" : 4, "age" : 4 }

    -$or

    > db.stu.find({$or: [{_id: {$lte: 2}}, {_id: {$gte: 4} }]})
    { "_id" : 1, "name" : "mynameishehe" }
    { "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
    { "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
    { "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }

    5. 分页查询

    skip()-  跳过的数据条数;即(pageNum-1)*pageSize

    limit(num)- 限制返回的数据条数; 即pageSize

    sort({key: 1/-1})- 按照key排序;其中1表示正序;-1表示倒序

    /**示例:返回排序后的第二页(pageSize=3)**/
    > db.stu.find();
    { "_id" : 1, "age" : 1 }
    { "_id" : 2, "age" : 2 }
    { "_id" : 3, "age" : 3 }
    { "_id" : 4, "age" : 4 }
    { "_id" : 5, "age" : 5 }
    { "_id" : 6, "age" : 6 }
    /**按照age字段正序排序后取第二页**/
    > db.stu.find().skip((2-1)*3).limit(3).sort({age:1})
    { "_id" : 4, "age" : 4 }
    { "_id" : 5, "age" : 5 }
    { "_id" : 6, "age" : 6 }
    /**按照age字段倒序排序后取第二页,**/
    > db.stu.find().sort({age: -1}).skip((2-1)*3).limit(3)
    { "_id" : 3, "age" : 3 }
    { "_id" : 2, "age" : 2 }
    { "_id" : 1, "age" : 1 }

    4. MongoDB数据库的备份和恢复

    mongo/mongodump/mongorestore都是全局命令

    1. 备份

    /**备份后的文件位于命令运行时所在文件夹下***/
    $ mongodump --out './bk' --collection stu --db test

    2. 从备份的数据恢复

    $ mongorestore './bk'

    5. 执行脚本

    mongo 文件名

    示例:脚本内容-insert.js

    var start = Date.now();
    var users = [];
    for(let i=0; i<10000; i++) {
      users.push({_id: i, name: 'lyra'+i, age: i});
    }
    db.stu.insert(users); /**批量插入;提高效率 **/
    var cost = Date.now() - start;
    print(cost + 'ms');

    运行脚本

    $ mongo insert.js
    MongoDB shell version v4.2.3
    connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
    Implicit session: session { "id" : UUID("0587a441-5c94-4166-8634-4e1e2ea3c8cd") }
    MongoDB server version: 4.2.3
    35ms
  • 相关阅读:
    tee:结果输出到文件同时也作为往后的输入信息
    hexdump:查看文件头部信息,以十六制形式查看文件
    删除大文件方法
    rename:批量更改文件名
    求从1加到100的结果
    简书里面的面试题
    开源好网站
    ubuntu 14上安装mysql离线包
    单点登录原理与简单实现---转
    Revit API 判断一个构件在某个视图中的可见性
  • 原文地址:https://www.cnblogs.com/lyraLee/p/12333140.html
Copyright © 2011-2022 走看看