PHP操作MongoDB學習

fmms 12年前發布 | 134K 次閱讀 PHP MongoDB NoSQL數據庫

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程序

   <?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);</pre> 



      注意的是,默認不用顯式create database即可,如果不存在則會自動
新建立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)));</pre>

   指定一定范圍內的記錄:

   $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,只修改記錄的某個部分,可以這樣:
   $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效率比較高
或者:
   $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)));</pre>

  使用.號來查詢子嵌套文檔
  {
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等平臺的驅動程序。

轉自:http://jackyrong.iteye.com/blog/1333419

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!