MongoDB入门(PHP)
MongoDB是目前一款比较流行的文档数据(document-oriented database), 类似的还有Apache CouchDB等。
安装
MongoDB安装非常简单,在http://www.mongodb.org下载对应版本(如Linux 32bit/64bit),解压即可。
PHP需要安装Mongo扩展(MongoDB driver for PHP),通过pecl或在http://pecl.php.net/package/mongo下载编译即可。
MongoDB服务启动/停止
例如:
./mongod --port 10001 \ --logpath=/var/logs/mongodb/mongod.log \ --dbpath=/var/data/db/ \ --pidfilepath /var/run/mongod.pid \ --directoryperdb
很多其它参数参考:
./mongod --help | less
停止服务,直接Ctrl+C或者kill `cat /var/run/mongod.pid`即可。
另外先提一下MongoDB提供的Shell客户端:./mongo, 很多操作需要使用它,例如数据管理配置等。
./mongo
默认连接到localhost:27017/test
./mongo 192.168.0.33:10001/blog
连接到192.168.0.33的服务器,端口为10001, 并使用blog数据库.
database与collection
MongoDB是free-schema数据库,所以文档结构不需要像关系型数据库一样严格定义,也没有类似create database, create table, alter table等之类的操作。
例如下面命令将工作数据库切换到blog,但blog并不需要预先create.
> use blog
对于collection也是类似,不需要预先创建, 下面命令将文档插入名为posts的collection.
> db.posts.insert({"title":"Hello, MongoDB", "date":new Date()})
Collection类似于关系型数据库的表.
注意到这里插入的简单文档看起来是一个JSON。MongoDB存储文档的格式正是JSON,不过是Binary JSON,所要又称为BSON.
PHP访问数据库
详细文档请参考:PHP:Mongo, 下面例举简单示例。
连接数据库:
$mongo = new Mongo("192.168.0.33:10001");
选择数据库:
//use database blog $blog = $mongo->blog;
选择Collection:
//collection posts $posts = $blog->posts;
写入数据:
$post = array( 'title'=>'Hello, MongoDB', 'content'=>'Great MongoDB
', 'date'=>new MongoDate(/*default=time()*/), 'views' => 0 ); //insert one document $posts->insert($post); $post2 = array( 'title' => 'Powerfull mongoDB', 'content' => 'Powerfull, mongoDB
', 'author' => 'James Tang', 'date' => new MongoDate(/*time()*/), 'views' => 0 ); //insert multiple documents $posts->batchInsert(array($post, $post2));
写入操作可以有可选参数, 如:
$posts->batchInsert(array($post, $post2),array( 'safe'=> true ));
‘safe’=>true 表示等待数据库响应再返回,如果写入失败则抛出MongoCursorException异常,其它参数参考文档。
更新:
//Query one document $post = $posts->findOne(array('title' => 'Hello, MongoDB')); if ($post) { $post['title'] = 'Hello, mongoDB 2'; //update $posts->update(array('_id'=> $post['_id']), $post); }
Upsert, 即更新或者新增加:
//use 'upsert' option of update() method $posts->update(array('title'=> $post['title']), $post, array( 'upsert'=>true, )); //use save() method, more convenient $posts->save($post);
MongoDB提供了更新操作符,如$inc, $set, $push, …
//$inc modifier, value of `views` field will increase one. $posts->update(array('_id'=> $post['_id']), array( '$inc' => array('views'=>1) )); //$set modifier, set the value of `views` to 0 $posts->update(array('_id'=> $post['_id']), array( '$set' => array('views'=>0) )); //$push adds an element to the end of an array //if the specified key already exists and //creates a new array if it does not. //a new field `tags` will be added for our example //and has one element `php` $posts->update(array('_id'=> $post['_id']), array( '$push' => array('tags'=>'php') ));
更多关于更新与操作符的信息,请参考:Updating。
删除:
$posts->remove(array( 'title' => 'Hello, mongoDB' )); //remove all document in the collections $posts->remove(); //more efficient than remove() $posts->drop();
简单查询:
//query one document $posts->findOne(/*criteria*/); //a cursor of documents $posts->find(/*criteria*/);
示例:
//query the document with title contains "mongoDB", case insensitive, //and only return the title, date fields. $cursor = $posts->find(array( 'title' => new MongoRegex('/mongoDB/i'), ),array( '_id'=>false, 'title', 'date' )); //sorting document $cursor->sort(array( 'title' => -1, //1-ascending, -1 descending )); //limit in 3 document $cursor->limit(3); foreach ($cursor as $post) { echo $post['title'] . "\n"; echo date('Y-m-d', $post['date']->sec) . "\n"; }
参考:http://www.mongodb.org/display/DOCS/Querying
“_id”与ObjectId
每一个Document都有一个_id属性,每个文档的_id必须唯一,如果创建文档时没有指定,Mongo客户端会自动生成一个_id,其值为ObjectId类型,在PHP中对应的类为MongoId.
“_id”也可以是其它类型,如Int, string,但不能是array。
ObjectId以12字节存储,其生成方法如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
Timestamp | Machine | PID | Increment |
- Timestamp精确到秒,如1320978110
- Machine为hostname, 或者Mac/网络地址, 或者虚拟机ID的MD5序列的前三字节
- Increment,类似于自增,所以在新增多个文档时可能这几位是连续的,但也可能是随机数
除了timestamp可以确定外,后面三部分可能会因客户端不同而生成方式有点差异。
例如ObjectId(“4ebc86bedf8a426362118b5d”),这是ObjectID的表示,4ebc86be对应1320978110。
但ObjectID之所以表示为24个字符的字符串,是因为第个字节以两个十六进制数表示。
总结
MongoDB更适合面向对象编程,free-schema能够更加敏捷地就会需求变化。其它高级特性及应用需要进一步学习。