PHP操作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 MongoDB 扩展安装
5.3 mongo driver下载:
http://downloads.mongodb.org/mongo-latest-php5.3vc6ts.zip
把DLL复制到extension目录,然后
extension=php_mongo.dll即可
5 列出当前数据库的php mongodb程序
<?php
try{
$mongo = new Mongo(); //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的策略;
try {
$mongo = new Mongo($options=array('timeout'=> 100))
} catch(MongoConnectionException $e) {
die("Failed to connect to database ".$e->getMessage());
}
6 通过PHP保存对象到mongo db中
$connection = new Mongo();
$database = $connection->selectDB('myblogsite');
$collection = $database->selectCollection('articles');
$article = array();
$article['title'] = $_POST['title'];
$article['content'] = $_POST['content'];
$article['saved_at'] = new MongoDate();
$collection->insert($article);
新建立database,也可以:
$connection = new Mongo();
$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 日期设置
$article['saved_at'] = new MongoDate();
$timestamp = new MongoDate(strtotime('2011-05-21 12:00:00'));
print date('g:i a, F j', $timestamp->sec); //prints 12 pm, May 21
$lastweek = new MongoDate(strtotime('-1 week')); //找出一个星期以来的记录
$cursor = $articleCollection->find(array('saved_at' =>
array('$gt' => $lastweek)));
指定一定范围内的记录:
$start = new MongoDate(strtotime('2011-05-01 00:00:00'));
$end = new MongoDate(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,只修改记录的某个部分,可以这样:
使用inc:$articles->update(array('_id' => MongoId('4dcd2abe5981')), array('$set' => array('title' => 'New Title')));
unset:$articles->update(array('_id' => MongoId('4dcd2abe5981')), array('$set' => array('content' => 'New Content'),
'$inc' => array('update_count' => 1)));
// 将update_count+1
更名rename:$articles->update(array('_id' => MongoId('4dcd2abe5981')), array('$unset' => array('title' => True)));
// 将title field从这个document中移除
$articles->update(array(),
array('$rename' => array('saved_at' => 'created_at')),
array('multiple' => True));
// 将save_at更名为create_at
14 删除记录
如果加了justOne的参数,则只删除符合条件的一条记录而已,其他不删除$articleCollection->remove(array('_id' => new MongoId($id)));
$movies->remove(array('genre' =>'drama'), array('justOne' => True));
15 document的关系
{
"_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")
}
$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)));
或者:
$article = $articleCollection->findOne(array('_id' => new MongoId($id)));
$comments = (isset($article['comments'])) ? $article['comments'] : array();
$comment = array(
'name' => $_POST['commenter_name'],
'email' => $_POST['commenter_email'],
'comment' => $_POST['comment'],
'posted_at' => new MongoDate()
);
array_push($comments, $comment);
$articleCollection->update(array('_id' => new MongoId($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'));
mongodb 数据备份及恢复 mongodump mongorestore
[root@localhost bin]# ./mongodump -d my_mongodb
connected to: 127.0.0.1
DATABASE: my_mongodb to dump/my_mongodb
my_mongodb.system.indexes to dump/my_mongodb/system.indexes.bson
1 objects
my_mongodb.user to dump/my_mongodb/user.bson
2 objects
[root@localhost bin]# ll
总计 67648
-rwxr-xr-x 1 root root 7508756 2011-04-06 bsondump
drwxr-xr-x 3 root root 4096 04-10 23:54 dump
-rwxr-xr-x 1 root root 2978016 2011-04-06 mongo
[root@localhost bin]# ./mongodump -d my_mongodb -o my_mongodb_dump
connected to: 127.0.0.1
DATABASE: my_mongodb to my_mongodb_dump/my_mongodb
my_mongodb.system.indexes to
my_mongodb_dump/my_mongodb/system.indexes.bson
1 objects
my_mongodb.user to my_mongodb_dump/my_mongodb/user.bson
2 objects
[root@localhost bin]#
接下来我们进行数据库恢复> use my_mongodb
switched to db my_mongodb
> db.dropDatabase()
{ "dropped" : "my_mongodb", "ok" : 1 }
> show dbs
admin (empty)
local (empty)
test (empty)
>
[root@localhost bin]# ./mongorestore -d my_mongodb my_mongodb_dump/*
connected to: 127.0.0.1
Wed Apr 11 00:03:03 my_mongodb_dump/my_mongodb/user.bson
Wed Apr 11 00:03:03 going into namespace [my_mongodb.user]
Wed Apr 11 00:03:03 2 objects found
Wed Apr 11 00:03:03 my_mongodb_dump/my_mongodb/system.indexes.bson
Wed Apr 11 00:03:03 going into namespace [my_mongodb.system.indexes]
Wed Apr 11 00:03:03 { name: "_id_", ns: "my_mongodb.user", key: { _id: 1 }, v: 0 }
Wed Apr 11 00:03:03 1 objects found
[root@localhost bin]#
mongodb php 模糊查询
MongoDB非正常关闭后修复记录
启动mongodb时,提示Unclean shutdown detected mongodb,解决方法很简单
mongod --repair --dbpath /var/db/mongodb
PHP操作MongoDB GridFS 存储文件
<?php
//初始化gridfs
$conn = new Mongo(); //连接MongoDB
$db = $conn->photos; //选择数据库
$grid = $db->getGridFS(); //取得gridfs对象
//gridfs有三种方式存储文件
//第一种直接存储文件
$id = $grid->storeFile("./logo.png");
//第二种存储文件二进制流
$data = get_file_contents("./logo.png");
$id = $grid->storeBytes($data,array("parame"=>’附加参数将随图片一起存入’));
//第三种保存直接表单提交的文件$_FILES
$id = $grid->storeUpload('upfile');
//相当于
$id = $grid->storeFile($_FILES[‘upfile’][‘tmp_name’]);
//--------------以上是保存图片--下面开始读取图片----------------
//保存成功后返回$id = md5字符串
$logo = $grid->findOne(array('_id'=>$id)); //以_id为索引取得文件
header('Content-type: image/png'); //输出图片头
echo $logo ->getBytes(); //输出数据流
?>
按照设计,MongoDB文档(BSON对象)不能超过16M,这是为了使性能保持在最高水平。如果文档超过16M,当查询时将占用大量的内存。
GridFS指定了将一个大文件分割成多个文档的机制。通过开发语言扩展来实现,例如php扩展,在存储时,分块存储,在检索时,合并分块。
开发人员无需知道内部细节,存储和处理文件是一个透明高效的方式。
GridFS存储在两个独立的集合中:文件和块。基本的想法是为每一个文件被存储在GridFS。文件将有一个文档包含文件名,大小,上传时间以及其他用户定义的元数据。文件的内容存储在一个或多个文档块中。 PHP是以256Kbyte大小来分块。
使用php来实现
# vi upload.html
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″/>
<title>Upload Files</title>
</head>
<body>
<h2>Select files to upload</h2>
<form enctype=”multipart/form-data” action=”/store.php” method=”post”>
<input type=”file” name=”file”><br>
<input type=”submit” name=”submit” value=”Upload”>
</form>
</body>
</html>
<?php
$host="127.0.0.1";
$port="27017";
$dbname="ttlsa";
$coname="ttlsa_com";
if($_FILES['file']['error'] !== 0){
die('Error upload file. Error code '.$_FILES['file']['error']);
}
$filename=$_FILES['file']['name'];
$filetype=$_FILES['file']['type'];
$tmpfilepath=$_FILES['file']['tmp_name'];
$conn = new Mongo("mongodb://".$host.":".$port,array('timeout'=>100));
$database = $conn->selectDB($dbname);
$collection = $database->selectCollection($coname);
$gridfs=$database->getGridFS();
$id=$gridfs->storeFile($tmpfilepath,array('filename'=>$filename,'filetype'=>$filetype));
echo "File Uploaded. ID: ".$id."\n";
?>
使用getBytes会有一个潜在的问题,将文件内容全部加载到内存中。如果读取大文件这种方式性能差。GridFS是将文件分块存储的,那么可以单独的从每个块读取和输出,从而避免上述问题。
<?php
$host="127.0.0.1";
$port="27017";
$dbname="ttlsa";
$id=$_GET['id'];
$conn = new Mongo("mongodb://".$host.":".$port,array('timeout'=>100));
$database = $conn->selectDB($dbname);
$gridfs=$database->getGridFS();
$object=$gridfs->findOne(array('_id'=>new MongoId($id)));
header('Content-type: '.$object->file['filetype']);
echo $object->getBytes();
?>