PHP7 MongoDB擴展

看看這都神馬函數名,還能再長一點嗎?要趕超swift的函數名嘛?
php

MongoDB\Driver\Manager::executeBulkWrite
java

這玩意還配置了一個巨大的類庫來配合調用:就是這個:https://github.com/mongodb/mongo-php-library   ,純粹是脫褲子放P,畫蛇添足,原本原生擴展就已經巨長、巨難用,還配一個根本沒有簡化任何代碼的庫有什麼意義?甚至於調用這個類庫比原生的名字更長、更囉嗦,並且多了一層封裝就多一次bug機會。git

這個庫文件總共63個,看看,若是你隨便寫個腳本訪問一下mongodb,還得包含63個文件,我TM整個項目都沒有63個文件好很差?這些個寫慣了java的沒事就老老實實寫java,都跑來寫php,php是要解析執行的,又不像jvm那麼編譯優化執行,搞那麼多文件,不影響執行速度嗎?真是狗屎,因此徹底不推薦用這個狗屎庫。github

可是這個擴展最奇怪的就是文檔超級簡陋,根本不能得到任何有價值的信息,因此只能靠摸索來了。mongodb

下面是我用到的由MongoClient遷移到MongoDB\Driver的差別點。
數據庫

MongoClient插入或更新是一樣的代碼:swift

(new MongoClient())->{$db}->{$collection}->save($arr);
// 這個$arr數組能夠直接含有 "_id" 索引來指定 mongodb文檔的_id值,就這麼簡單粗暴,這纔是php啊!

MongoDB\Driver,插入和更新須要區分:數組

$mongo = new MongoDB\Driver\Manager();
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => true]);
$data = $mongo->executeQuery('db.collection', new MongoDB\Driver\Query([]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED))->toArray();
if (empty($data[0])) { // 肯定不存在,插入
    $bulk->insert($arr);
} else { // 否者更新
    $bulk->update([], array('$set' => $arr)); // $arr一樣是剛纔的數組
}
// 還沒完,還要執行下一步:db.collection要替換成實際的數據庫、集合名
$result = $mongo->executeBulkWrite('db.collection', $bulk, new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000));
// 返回插入或更新是否成功:
$ok = $result->getInsertedCount() || $result->getModifiedCount() ? 1 : 0;
// 真是夠了!

查詢一條記錄:jvm

MongoClient:函數

(new MongoClient())->{$db}->{$collection}->findOne(['_id' => $id]);

MongoDB\Driver:

$mongo = new MongoDB\Driver\Manager();
$result = $mongo->executeQuery('db.collection', new MongoDB\Driver\Query(['_id'=>$id], []), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED));
// 返回的$result是一個對象,須要手動轉換成數組。

查詢數量時候,須要注意:

$mongo = new MongoDB\Driver\Manager();
$cursor = $mongo-executeCommand($db, new MongoDB\Driver\Command($arr), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED));
// 這裏$cursor是一個遊標。須要注意$arr裏的字段:
$arr = ['count'=>$collection, 'query'=>$query]; // 這裏count必須排在前面,位置反了直接報異常。

查詢結果集:

$mongo = new MongoDB\Driver\Manager();
$cursor = $mongo->executeQuery('db.collection', new MongoDB\Driver\Query($arr, $opts), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED));
//注意,這裏的 $arr和 $opts;
$arr = ['_id'=> ['$in'=> $ids] ]; // 根據id數組獲取集合
$opts = ['limit'=> $limit, 'skip'=> $skip ]; // 不推薦
// 這裏在傳遞$limit和$skip的時候,最好先轉成整數,否則不生效:
$opts = ['limit'=> (int) $limit, 'skip'=> (int) $skip ]; // 推薦寫法。
// 寫到這裏,讓人懷疑是否是在用php了,怎麼還須要這樣的類型轉換。字符串整數都不行!

基本就這樣,推薦本身封裝一個簡單的MongoDB\Driver,而不是使用那個巨大無比的庫、也不推薦直接用原生。