Mac收集我爱编程

Node学习笔记三:Hello MongoDB

2015-09-05  本文已影响375人  PM熊叔

1.安装

1.1 使用brew安装

Mac 上面比较简便的安装方法是使用brew
由于网络环境的限制,安装的时候可以设置代理

http_proxy=https://ip:port brew install mongodb

如果报错,先升级 brew

http_proxy=https://ip:port brew update

如果还是没有用,可以通过设置好代理的浏览器中输入brew请求的下载地址,进行下载。下载完毕后,将mongodb-3.0.6.yosemite.bottle.tar.gz移动到Library/Caches/Homebrew中(此目录存放着brew下载好包文件)再重新执行 brew install mongodb

测试是否安装成功,执行命令mongod

mongod
2015-09-14T09:00:32.799+0800 I STORAGE  [initandlisten] exception in initAndListen: 29 Data directory /data/db not found., terminating
2015-09-14T09:00:32.800+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

从提示可以看出,需要创建/data/db目录,现在我们设置一下,执行以下两行命令:

 sudo mkdir -p /data/db
 sudo chown `id -u` /data/db

-p是如果当前的父级目录不存在则创建它;
id -u是将所有者指定到当前用户;用whoami也起相同的效果;

  sudo chown `whoami` /data/db

最后再执行一下mongod就可以看到效果了;

mongod

参考资料:https://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/

1.2 安装可视化工具mongohub

https://github.com/jeromelebel/MongoHub-Mac 下载MongoHub.zip文件,解压后拖入到应用程序中即可使用。使用起来也非常方便,摸一摸就会了。

2.使用MongoDB

2.1 使用mongodb 模块

安装mongodb模块

npm install mongodb 

打开app.js文件,添加以下代码;

//引入模块
var mongodb = require('mongodb');

//创建一个连接实例,连接到MongoDB服务器
//主机的地址为localhost、端口号未27017。
//auto_reconnect:true,表示在链接中断后能够自动重新连接
var dbServer =new mongodb.Server('localhost', 27017,{auto_reconnect:true});

//创建一个数据库名为mydb
//第二个参数是上面创建的连接实例
//{w:1}是配置
var db = new mongodb.Db('mydb',dbServer,{w:1});

{w:1}是写入相关设置,表明这个是主mongod实例,只要你的 服务器上不超过一个MongoDB实例,就可以这样写。更多请参考:http://docs.mongodb.org/master/core/write-concern/

2. 2添加数据

首先我们要解释一下概念:Mongodb的结构中的“数据库”、“集合”、“文档”分别对应关系型数据库的:“数据库”、“表”、“行”的概念

db.open(function(err,conn){
});

db.open()用于打开数据库,内部参数是一个异步回调函数

db.open(function(err,conn){
    //创建一个名为myCollection的集合
    db.collection('myCollection',function(err, collection){
        var count = 0;
        for (var i=0;i<5;i++){
            //插入一个文档到集合
            collection.insert({
                num:i
            },function(err,result){
               //输出结果
                console.log(result);
                //添加计数
                count++;
                //如果计数器足够大,则关闭链接
                if(count>4){
                    db.close();
                }
            });
        }
    });
});

collection.insert({},function(err,result){})第一个参数是要插入的内容,第二个参数是插入成功时的回调函数;由于是插入数据不是顺序执行的,也就是说i=1可能会最后一个插入完成,整个插入顺序可能是3、4、2、1,如果通过if(i>4){}来判断何时执行断开,可能会导致提前断开。因此需要添加一个外部计数器,每次插入成功后count加一,当count大于4的时候断开连接。

2.3 读取数据

2.3.1 读取所有数据

修改刚才的db.open()中的代码,使用collection.find()读取数据:

db.open(function(err,conn){
    //选择集合
    db.collection('myCollection',function(err, collection){
        // 选择集合中所有的文档
        collection.find().toArray(function(err,result){
           //输出数据
            console.log(result);
            //关闭链接
            db.close();
        });
    });
});

输出数据,如下:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 2 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

我们可以看出,虽然插入数据时结束的时间是无序的,但是插入时候的MongoDB的ID是有序的。

2.3.2 读取特定数据:

collection.find()没有特定参数时,为选择所有;如果需要选择查询特定内容时可以添加参数,例如我们要查询num为2的所有数据可以设置find()为find({num:2}),mongodb会返回所有满足条件的数据,由于我们只有一条满足需求的数据,因此返回的集合中只有一条数据:

[ { _id: 55f65ff1ae0f94286cdabf19, num: 2 } ]

明明是一条数据,能不能不以集合的方式返回呢?
我们可以使用findOne()方法

 collection.findOne({num:2},{},function(err,result){
               console.log(result);
               db.close({});
           });

返回结果

{ _id: 55f65ff1ae0f94286cdabf19, num: 2 } 
范围条件查询

如果我们要查询所有num>2的数据,我们可以将find()参数设置为{num:{$gt:2}} $gt 操作符是great than 的缩写,运行后MongoDB返回两条数据:

[ { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

如果我们要查询num<2的数据,我们可以使用$lt lt 是little than 的缩写;设置find({num:{$lt:2}}),返回结果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 } ]

$gt$lt可以组合使用,如果是num介于1和4之间,使用find({num:{$lt:4,$gt:1}})可以返回结果:

[ { _id: 55f65ff1ae0f94286cdabf19, num: 2 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 } ]

更多操作符请参看:http://docs.mongodb.org/manual/reference/operator/

2.3.3 限制显示条数和配需

find()的一个参数是一个json对象,主要用于查询条件;第二个参数也是一个json对象,用于显示限制及排序:limit属性可以限制返回的条数,设置find({},{limit:2})第一个参数为{}表示查询所有),查看返回结果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 } ]

排序:按照num进行降序排列:
find({},{limt:2,sort:[['num','desc']]}) (注意 是两层的[],因为你还能更具需要做不同优先级的排序),返回结果:

[ { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 } ]

2.4 更新数据:

2.4.1 更新单条数据

collection.update()方法可以用来更新数据,修改db.open()为以下代码:

db.open(function(err,conn){
    
     //选择集合`myCollection`
    db.collection('myCollection',function(err, collection){
        
       // 更新集合中所有的文档
        collection.update({num:2}, {num:10}, {safe: true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            //查看集合中的内容
            collection.find().toArray(function(err,result){
                console.log(result);
                db.close({});
            });
        });
    });
});

返回结果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

从上面的例子可以看出update()接受四个参数:

  1. 更新条件: { num:2 }表示更新num为2的记录,这里也可以使用find()中的高级操作符,例如{num:{$lt:3}}更新num小于3的记录:
[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10},
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

但是奇怪的事情发生了,num:1 不是也小于3吗,为何不更新?因为update() 一次只能更新一条,所以会先去更新num:0,如果你现在用Ctrl+C停止服务后再执行npm start 返回的结果才为你预想的那样:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10},
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]
  1. 要做的修改:本例中将满足条件的记录改成num:10;
  2. 更新选项:{safe: true}表示设置安全模式,这个应该一直使用;{mult: true}允许更新更多文档也是很常用的选项;
  3. 回调函数:操作成功或者失败后执行的函数,在这里我们除了在终端输出错误信息外,还使用collection.find()查看操作后的变化;

2.4.2 更新或者插入

在更新选项对象中设置{upsert:true},upsert 既是 update + insert ,如果查询的该条记录存在那么就是update,如果不存在就insert一条符合条件的数据。我们来试一试,修改上面的代码:

//如果有的话将num:8修改为num:7 ;如果没有的话,就插入一条num:7
 collection.update({num:8}, {num:7}, {safe: true,upsert:true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            collection.find().toArray(function(err,result){
                console.log(result);
                db.close({});
            });
  });

发现返回的结果中多了一条num:7的数据;

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 } ]

2.4.3 为指定文档添加字段和值

之前,都是在相应的文档中做原有字段的值的修改,如果需要添加新的字段怎么办?
可以用$set,代码如下:

 collection.update({num:3}, {$set:{desc:'favorite number'}}, {safe: true,upsert:true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            collection.find().toArray(function(err,result){
                console.log(result);

                db.close({});
            });

        });

返回结果

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

可以看出,我们update() 的第二个参数中使用了{$set:{desc:'favorite number'}为num: 3 这条数据添加了desc字段,并且值为:favorite number

2.4.4 查找并修改

2.5 删除数据

2.5.1 移除文档(行)

remove()可以移除整行的数据,修改之前的代码:

    db.collection('myCollection',function(err, collection){
        // 删除集合中num=4的文档
        collection.remove({num: 4},function(err){
           if(err){
               console.log(err);
           }else{
               console.log("Successfully removed");
           }
           collection.find().toArray(function(err,result){
               console.log(result);
               db.close({});
           });
        });
    });

返回结果,可以看出 num: 4的文档被成功删除:

Successfully removed
[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

如果将删除条件{num: 4}改成{num:10}的会产生怎么样的效果呢?
我们看返回的结果:

Successfully removed
[ { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

所有num:10的文档统统被删除了。因此,我们应当特别注意:
remove()是一次性针对所有满足条件的数据做操作

2.5.2 删除数据集合(表)

使用dropCollection()可以删除指定的集合;

db.open(function(err,conn){
    db.dropCollection('myCollection',function(err, result){
        if(err){
            console.log(err);
        }else{
            console.log(result);
        }
        db.close();

    });
});

返回

true

一定要慎重!

上一篇 下一篇

猜你喜欢

热点阅读