PHP操作MongoDB学习,转

1 mongodb启动时,设置启动项

C:\>mongodb\bin\mongod --config C:\mongodb.conf

其中mongodb.conf为:

dbpath = D:\mongodb_data

logpath = D:\mongodb.log

logappend = true

如果是linux的话,则mongod --config /etc/mongodb.conf

2 停止server

db.shutdownServer()

3 常用操作:

use myfirstdb

插入db

db.movies.insert({name:"Source Code", genre:"sci-fi", year:2011})

查找所有记录

db.movies.find()

4 php 5.2 mongo driver下载:

http://downloads.mongodb.org/mongo-latestphp5.2vc6ts.

zip

5.3 mongo driver下载:

http://downloads.mongodb.org/mongo-latest-php5.3vc6ts.zip

把DLL复制到extension目录,然后

extension=php_mongo.dll即可

5 列出当前数据库的php mongodb程序

?

1

2

3

4

5

6

7

8

9

10

11

12

<?php

try{

$mongo=newMongo();//create a connection to MongoDB

$databases=$mongo->listDBs();//List all databases

echo'<pre>';

print_r($databases);

$mongo->close();

}catch(MongoConnectionException$e) {

//handle connection error

die($e->getMessage());

}

?>

如果是连接时用不同的端口,构造函数中用:

$mongo = new Mongo($server="mongodb://localhost:8888");

也可以指定timeout的策略;

?

1

2

3

4

5

try{

$mongo=newMongo($options=array('timeout'=> 100))

}catch(MongoConnectionException$e) {

die("Failed to connect to database ".$e->getMessage());

}

6 通过PHP保存对象到mongo db中

?

1

2

3

4

5

6

7

8

9

10

$connection=newMongo();

$database=$connection->selectDB('myblogsite');

$collection=$database->selectCollection('articles');

$article=array();

$article['title'] =$_POST['title'];

$article['content'] =$_POST['content'];

$article['saved_at'] =newMongoDate();

$collection->insert($article);

注意的是,默认不用显式create database即可,如果不存在则会自动

新建立database,也可以:

?

1

2

3

4

5

6

7

8

9

10

11

$connection=newMongo();

$collection=$connection->myblogsite->articles;

mongodb的插入是异步的,如果不想异步,可以这样;

try{

$status=$connection->insert(array('title'=>'Blog Title',

'content'=>'Blog Content'),

array('safe'=> True));

echo"Insert operation complete";

}catch(MongoCursorException$e) {

die("Insert failed ".$e->getMessage());

}

则必须等插入完成后才返回给用户,继续执行下一条语句

也可以指定timeout的策略:

$collection->insert($document, array('safe' => True,

'timeout' => True));

7 设置自己的自增id

$document = array('_id' => hash('sha1', $username.time()),

将设置id为username后加上当前时间再hash.

8 日期设置

?

1

2

3

4

5

6

7

$article['saved_at'] =newMongoDate();

$timestamp=newMongoDate(strtotime('2011-05-21 12:00:00'));

printdate('g:i a, F j',$timestamp->sec);//prints 12 pm, May 21

$lastweek=newMongoDate(strtotime('-1 week'));//找出一个星期以来的记录

$cursor=$articleCollection->find(array('saved_at'=>

array('$gt'=>$lastweek)));

指定一定范围内的记录:

?

1

2

3

4

5

$start=newMongoDate(strtotime('2011-05-01 00:00:00'));

$end=newMongoDate(strtotime('2011-05-31 23:59:59'));

$articleCollection->find(array('saved_at'=>

array('$gte'=>$start,

'$lte'=>$end)));

9 列出某个表的所有记录

$cursor = $collection->find();

<?php while ($cursor->hasNext()):

$article = $cursor->getNext(); ?>

<h2><?php echo $article['title']; ?></h2>

............

找某条记录:$article = $collection->findOne(array('_id'=>

new MongoId($id)));

查找时也可以传入多个参数:

$moviesCollection->find(array('genre' => 'comedy', 'year' => 2011));

if ($cursor->count() === 0) //如果找不到

如果查询多个条件:

$collection->find(array('x' => array('$gt' => 100)));

//$ is escaped within double quotes (")

$collection->find(array('x' => array("\$gt" => 100)));

注意要用单引号,如果要用双引号,则要加上转义符。

10 排序:

$cursor->sort(array('saved_at' => -1)) //按save_at字段降序排列,1为升序

11 skip和limit:

$cursor = $articleCollection->find();

//skip the first five articles in the cursor

$cursor->skip(5);

$cursor->limit(10);//结果集只取10条

12 更新数据库

$articleCollection->update(array('_id' => new MongoId($id)),

$article);

第一个参数为指定的条件(更新条件),第二个参数为要更新的对象

还有可选参数如下;

$collection->update($criteria, $newobj, array('safe' => True));

safe=true时,等到UPDATE结束才返回结果

mongodb还支持upsert的操作:如果存在则更新,如果不存在则插入

$users->update(array('email' => 'alice@wonderland.com'),

array('firstname' => 'Alice', 'lastname'=> 'Liddell'),

array('upsert' => True));

这里对email为alice@wonderland.com的记录进行更新其firstname,lastname字段的内容

13 修饰符

比如set,只修改记录的某个部分,可以这样:

$articles->update(array('_id' => MongoId('4dcd2abe5981')),

array('$set' => array('title' => 'New

Title')));

使用inc:

$articles->update(array('_id' => MongoId('4dcd2abe5981')),

array('$set' => array('content' => 'New Content'),

'$inc' => array('update_count' => 1)));

将update_count+1

unset:

$articles->update(array('_id' => MongoId('4dcd2abe5981')),

array('$unset' => array('title' => True)));

将title field从这个document中移除

更名rename:

$articles->update(array(),

array('$rename' => array('saved_at' =>

'created_at')),

array('multiple' => True));

将save_at更名为create_at

14 删除记录

$articleCollection->remove(array('_id' => new MongoId($id)));

$movies->remove(array('genre' =>'drama'),

array('justOne' => True));

如果加了justOne的参数,则只删除符合条件的一条记录而已,其他不删除

15 document的关系

1)嵌套

{

"_id" : ObjectId("4dd491695072aefc456c9aca"),

"username" : "alphareplicant",

"email" : "roybatty@androids.org",

"fullname" : "Roy Batty",

"joined_at" : ISODate("2011-05-19T03:41:29.703Z"),

"address" : {

"street" : "13 Tannhauser Gate",

"city" : "Caprica",

"state" : "CC",

"zipcode" : 512

},

}

2)引用

{

_id : ObjectId("4dcd2abe5981aec801010000"),

title : "The only perfect site is hind-site",

content : "Loren ipsum dolor sit amet…",

saved_at : ISODate('2011-05-16T18:42:57.949Z'),

author_id : ObjectId("4dd491695072aefc456c9aca")

}

3)比如一个一对多的关系:

比如一个文章下的评论:

$comment = array(

'name' => $_POST['commenter_name'],

'email' => $_POST['commenter_email'],

'comment' => $_POST['comment'],

'posted_at' => new MongoDate()

);

$collection->update(array('_id' => new MongoId($id)),

array('$push' => array('comments' =>

$comments)));

使用的是$push的修饰符,一般来说,用内嵌的document效率比较高

或者:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

$article=$articleCollection->findOne(array('_id'=>newMongoId($id)));

$comments= (isset($article['comments'])) ?$article['comments'] :array();

$comment=array(

'name'=>$_POST['commenter_name'],

'email'=>$_POST['commenter_email'],

'comment'=>$_POST['comment'],

'posted_at'=>newMongoDate()

);

array_push($comments,$comment);

$articleCollection->update(array('_id'=>newMongoId($id)),array('$set'=>array('comments'=>

$comments)));

使用.号来查询子嵌套文档

{

name : "Gordon Freeman",

address : {

city : "Springfield",

state : "Florida"

}

}

{

name : "Lara Croft",

address : {

city : "Miami",

state: "Florida"

}

}

则查询address中state为florida的document:

$users->find(array('address.city' => 'Springfield',

'address.state' => 'Florida'));

Mongo是一个高性能,开源,模式自由(schema-free)的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值(key-value)存储方式。Mongo使用C++开发,具有以下特性:

l 面向集合的存储:适合存储对象及JSON形式的数据。

l 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。

l 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。

l 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。

l 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。

l 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。

l 自动分片以支持云级别的伸缩性(处于早期alpha阶段):自动分片功能支持水平的数据库集群,可动态添加额外的机器。

模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。

存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各中复杂的文件类型。我们称这种存储形式为BSON(Binary Serialized dOcument Format)。

MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。

MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。

MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。

根据项目主页的描述,Mongo适合用于以下场景:

l 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

l 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。

l 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。

l 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。

l 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。

自然,MongoDB的使用也会有一些限制,例如它不适合:

l 高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。

l 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。

l 需要SQL的问题

MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。