美文网首页
关于MongoDB的学习

关于MongoDB的学习

作者: PYM_祺 | 来源:发表于2018-01-07 13:10 被阅读0次

    nosql之间的比较

    memcached key-value缓存
    redis key-value存储数据库
    mongoDB 文档数据库,存储的是文档(Bson->json的二进制文件)
    特点:内部执行引擎js解释器,把文档存储为bson结构,查询时,转换为JS对象,并可以通过熟悉的js语法来操作。

    mongo和传统型数据库相比最大的不同

    传统型数据库:结构化数据,定好了表结构后,每一行的内容,必须是符合表结构的,列的个数和类型都一样。
    mongo文档型数据库:表下面的每篇文档都可以有自己独特的结构。

    {
        mid:3,
        author: xxx,
        conment:  [
            {
                cid:97,
                content:'好电影!'
            },
            {
                cid:98,
                content:'确实好!',
                reply: [
                    {
                        rid: 3,
                        content: '你说的对'
                    }
                ]
            }
        ]
    }
    

    安装

    1. 下载mongodb www.mongodb.org 下载最新stable版
    2. 解压文件
    3. 不用编译,本身就是编译后的二进制可执行文件


      mongo可执行文件介绍
    4. 启动mongodb服务
    /path/bin/mongod --dbpath /path/to/database --logpath /path/to/log-file --fork --port 27017
    

    参数解释:

    • --dbpath 数据存储目录
    • --logpath 日志存储文件
    • --port 运行端口(默认27017)
    • --fork 后台进程运行
    1. mongodb非常占磁盘空间,刚启动要3-4G空间,如果用虚拟机练习,可能空间不够用,导致无法启动,可以用
    --smallfiles 
    

    选项来启动,将会占用较小空间,400M左右。

    1. 连接mongo
    /path/bin/mongo
    

    1. mongo入门命令

    1.1 查看当前数据库

    show dbs;
    

    1.2 选库

    use databaseName;
    

    1.3 查看当前库下的表(在MySQL中叫tables,在mongo中叫collections)

    show tables/collections;
    

    1.4 mongo中use一个不存在的库时,会自动创建这个库(称为:隐式创建)

    use dbname
    

    1.5 显式创建一个表(如果你不创建,直接向其中加入一个文档,该Collection也会被隐式创建出来)

    use dbname; //先选库
    db.createCollection('name'); // 通过db对象的方法创建库
    

    1.6 删除一个表(Collection)

    use dbname; // 先选库
    db.collectionName.drop(); // 通过db中collection对象的方法删除库
    

    1.7 删除数据库

    use dbname; //先选库
    db.dropDatabase(); // 通过db对象的方法删除库
    

    2. 基本操作-增删改查


    • 语法: db.collectionName.insert(document);
    use dbname;
    // 增加单个文档
    db.collectionName.insert({title:'nice day'});
    // 增加多个文档
    db.collectionName.insert([
        {"title":"nice day"},
        {"name":"lili", "age":16}
    ]);
    // 查看, 若没_id这个字段,mongo会自动增加这个字段
    db.collectionName.find();
    

    • 语法: db.collectionName.remove(查询表达式,选项);
    use dbname;
    // 这条会报错
    db.collectionName.remove();
    // 全部删除
    db.collectionName.remove({});
    // 删除name为lili的数据
    db.collectionName.remove({"name":"lili"});
    // 删除age为19的数据,所有age=19的数据都会被删除
    db.collectionName.remove({"age":19});
    // 只删一条age为19的数据
    db.collectionName.remove({"age":19}, true);
    

    • 语法: db.collectionName.update(查询表达式,新值,选项);
      选项 {upset:true/false, multi:true/false}
      upsert 是指没有匹配的行,则直接插入该行
      multi 是指修改多行(即使查询表达式命中多行,默认也只改1行,如果想修改多行,可以用此选项)
    use dbname;
    // 将name=lilei的数据age改为32,这里会将这条数据变为只有_id和age的数据!
    db.collectionName.update({"name":"lilei"}, {"age":32});
    // 修改单个字段的正确方式$set
    db.collectionName.update({"name":"lilei"}, {$set:{"age":32}});
    // 修改单个字段并添加选项
    db.collectionName.update({"name":"lilei"}, {$set:{"age":32}}, {upsert: true});
    

    • 语法:
      db.collectionName.find(查询表达式,选项);
      db.collectionName.findOne(查询表达式,选项);
    use dbname;
    // 查询所有,展示所有列
    db.collectionName.find();
    // 带表达式和选项,选项表示要查age列(_id始终都有)
    db.collectionName.find({"name": "hmm"}, {"age": 1});
    // 查询一行
    db.collectionName.findOne({"age": 1});
    

    3. 查询表达式

    1. 最简单的查询表达式 { field : value}
      查询field为value的文档。
    2. $ne 不等与
      语法: { field : {$ne : value}}
    use dbname;
    // 查询age≠19的数据
    db.collectionName.find({"age": {$ne:19}});
    
    1. $in 在某数组中
      语法: { field : {$in : [value1, value2, ....]}}
    use dbname;
    // 查询goods表中cat_id为2或8的文档
    db.goods.find({"cat_id" : {$in : [2, 8]}});
    
    1. $nin 不在某数组中 not in
      语法: { field : {$nin : [value1, value2, ....]}}
    use dbname;
    // 查询goods表中cat_id不为2或8的文档
    db.goods.find({"cat_id" : {$nin : [2, 8]}});
    
    1. $all field的值为数组,且至少包含所给值
      语法: { field : {$all : [value1, value2, ....]}}
    2. $exists 查询含有某字段的文档
      语法: { field : {$exists : 1}}
    use dbname;
    // 查找含有age字段的文档
    db.collection.find({"age" : {$exists:1}});
    
    1. $nor 返回所有条件都不满足的文档
      语法: { $nor : [条件1, 条件2]}
    2. 正则表达式查询
    use dbname;
    // 查询产品名以诺基亚开头的文档
    db.collectionName.find({"goods_name" : /诺基亚.*/}, {"goods_name" : 1});
    
    1. $where 表达式查询
      注意:用$where查询时,mongodb是把bson结构转为json对象,然后比较对象的属性是否满足表达式,所以速度交慢。
    use dbname;
    // 查找cat_id≠3且cat_id≠11的文档
    db.collection.find({$where : "this.cat_id != 3 && this.cat_id != 11"});
    

    4. 游标操作

    游标是什么?
    通俗的说,游标不是查询结果,而是查询的返回资源或者接口,通过这个接口,你可以逐条读取。就像php中fopen打开文件,得到一个资源句柄一样,通过这个句柄,可以一行一行的读文件。

    use dbname;
    // 声明游标
    var cursor = db.collectionName.find(query, projection);
    // 判断游标是否已经取到尽头
    cursor.hasNext(); 
    // 取出游标的下一个单元,是bson结构,人无法识别
    cursor.next();
    
    // 用while来循环游标
    var mycursor = db.bar.find({"_id" : {$gt: 5}});
    while(mycursor.hasNext()) {
        // 通过printjson打印这个bson文档
        printjson(mycursor.next());
    }
    
    // foreach 也可以
    mycursor.foreach(function (obj) {
        printjson(obj);
    })
    

    5. group分组(求平均,求和等)

    方法: aggregate

    db.goods.aggregate([
        // 匹配哪些行
        {$match: {}}, 
        // 针对哪个字段分组,别名:$field
        // 根据哪个字段求值 , 别名 : { $求值方法 : "$field"}
        {$group: {"bieMin": "$cat_id", "total" : {$sum: "$price"}}}, 
    ]);
    
    mongoDB分组示意图

    6. Map-Reduce(分布式的group)

    相比aggregate聚合操作,Map-Reduce支持分布式的数据(大数据,在不同的地点、服务器上)。
    先 map: 分类。
    后 reduce: 统计。

    use dbname;
    
    // map 函数
    var map = function () {
        // 将cat_id相同的文档的goods_number放一起
        // this指的是遍历的每条数据
        emit(this.cat_id, this.goods_number);
    };
    
    // reduce 函数
    var reduce = function (cat_id, numbers) {
        // 分类好后,根据cat_id字段中的numbers来求和
        return Array.sum(numbers);
    };
    
    // 进行mapReduce操作,第三个参数表示将输出结果放到res这个表中
    db.goods.mapReduce(map, reduce, {out:"res"});
    // 查看结果
    db.res.find();
    

    相关文章

      网友评论

          本文标题:关于MongoDB的学习

          本文链接:https://www.haomeiwen.com/subject/jtspnxtx.html