PHP7使用 MongoDB\Driver\Manager 类实现简单的增删改查操作

MongoDB 是一个由 C++ 语言编写的,基于分布式文件存储的数据库。官方号称是“现代应用程序中最流行的数据库”(The most popular database for modern apps)。

今天,我们 PHP7 使用 MongoDB\Driver\Manager 类来演示一下简单的增删改查操作。

查看 MongoDB 扩展文档,主要有一下几组类:

MongoDB\Driver // MongoDB驱动类 
MongoDB\BSON   // BSON 类型与序列化函数
MongoDB\Driver\Monitoring // 监控
MongoDB\Driver\Exception  // 异常

基本操作用的都是 MongoDB\Driver 下的操作类:

MongoDB\Driver\Manager   // 入口类,负责维护与MongoDB的连接,执行读写和命令
MongoDB\Driver\BulkWrite // 收集要发送到服务器的一个或多个插入、更新、删除等操作
MongoDB\Driver\Query  // 构造查询对象
MongoDB\Driver\Cursor // 封装MongoDB命令或查询的结果
MongoDB\Driver\WriteResult // 封装执行结果

准备

首先确保已经安装好了 php-mongodb 扩展。

$ php -m |grep mongodb
mongodb

查看当前 PHP 版本:

$ php -v
PHP 7.4.0beta4 (cli) (built: Aug 28 2019 11:41:49) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.0beta4, Copyright (c), by Zend Technologies

创建一个 MongoDB 连接:

创建一个 mongodb.php 文件

<?php
// 连接 MongoDB 数据库
$manager = new MongoDB\Driver\Manager("mongodb://192.168.10.10:27017");
var_dump($manager);

如果连接正常会返回如下结果:

$ php mongodb.php
object(MongoDB\Driver\Manager)#1 (2) {
  ["uri"]=> string(29) "mongodb://192.168.10.10:27017"
  ["cluster"]=> array(1) {
    [0]=> array(10) {
      ["host"]=> string(13) "192.168.10.10"
      ["port"]=> int(27017)
      ["type"]=> int(1)
      ["is_primary"]=> bool(false)
      ["is_secondary"]=> bool(false)
      ["is_arbiter"]=> bool(false)
      ["is_hidden"]=> bool(false)
      ["is_passive"]=> bool(false)
      ["last_is_master"]=> array(10) {
        ["ismaster"]=> bool(true)
        ["maxBsonObjectSize"]=> int(16777216)
        ["maxMessageSizeBytes"]=> int(48000000)
        ["maxWriteBatchSize"]=> int(100000)
        ["localTime"]=> object(MongoDB\BSON\UTCDateTime)#2 (1) {
          ["milliseconds"]=> string(13) "1592379129886"
        }
        ["logicalSessionTimeoutMinutes"]=> int(30)
        ["minWireVersion"]=> int(0)
        ["maxWireVersion"]=> int(7)
        ["readOnly"]=> bool(false)
        ["ok"]=> float(1)
      }
      ["round_trip_time"]=> int(0)
    }
  }
}

如果连接了一个不存在的地址,会返回如下结果。因为不管连接的地址存不存在,都会返回一个MongoDB\Driver\Manager对象:

$ php mongodb.php
object(MongoDB\Driver\Manager)#1 (2) { 
 ["uri"]=> string(30) "mongodb://192.168.10.102:27017" 
 ["cluster"]=> array(0) { } 
}

增:插入一些数据

使用 MongoDB\Driver\BulkWrite 类进行操作:

英文单词 bulk 大量 + write 写,就是大量的写入,即进行批量写入操作(insert, update, delete)。

$manager = new MongoDB\Driver\Manager("mongodb://192.168.10.10:27017");

$bulk = new MongoDB\Driver\BulkWrite();
$id1 = $bulk->insert([
    'product_id'        => 101,
    'product_name'      => '俱乐部全犬种成犬粮天然健康狗粮10kg',
    'product_price'     => 269.00,
    'created_at' => new MongoDB\BSON\UTCDateTime(),
]);
$id2 = $bulk->insert([
    'product_id'        => 102,
    'product_name'      => '泰迪成犬粮专用狗粮2.5kg',
    'product_price'     => 245.00,
    'created_at' => new MongoDB\BSON\UTCDateTime(),
]);
$id3 = $bulk->insert([
    'product_id'        => 103,
    'product_name'      => '中小型成犬粮牛肉蔬菜狗粮500g',
    'product_price'     => 14.00,
    'created_at' => new MongoDB\BSON\UTCDateTime(),
]); 

var_dump('--> ID 1 是: ' . $id1);
var_dump('--> ID 2 是: ' . $id2);
var_dump('--> ID 3 是: ' . $id3);

try {
    $result = $manager->executeBulkWrite('testdb.products', $bulk);
    var_dump($result->getInsertedCount());
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
    var_dump($e->getWriteResult()->getWriteErrors());
}

例子中 testdb.products, 是指定操作 testdb 数据库中的 products 集合(类似与MySQL的表)。

例子中使用 MongoDB\BSON\UTCDateTime() 来生成 UTC 时间:

ISODate("2020-06-17T07:32:09.885Z")

MongoDB\BSON\UTCDateTime Object(
  [milliseconds] => 1592379129885
)

执行返回结果如下:

$ php mongodb.php
string(40) "--> ID 1 是: 5ee9c6f993d70221cc0dc56b"
string(40) "--> ID 2 是: 5ee9c6f993d70221cc0dc56c"
string(40) "--> ID 3 是: 5ee9c6f993d70221cc0dc56d"
int(3)

查:执行查询操作

使用 MongoDB\Driver\Query 进行查询操作

$manager = new MongoDB\Driver\Manager("mongodb://192.168.10.10:27017");

$filter = ['product_price' => ['$gt' => 100]];
$options = [
    'projection' => ['_id' => 0],
    'sort' => ['product_price' => 1],
];

$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery('testdb.products', $query);

foreach ($cursor as $document) {
    print_r($document);
}

查询结果如下:

$ php mongodb.php
stdClass Object (
    [product_id] => 102
    [product_name] => 泰迪成犬粮专用狗粮2.5kg
    [product_price] => 245
    [created_at] => MongoDB\BSON\UTCDateTime Object (
        [milliseconds] => 1592379129885
    )
)
stdClass Object (
    [product_id] => 101
    [product_name] => 俱乐部全犬种成犬粮天然健康狗粮10kg
    [product_price] => 269
    [created_at] => MongoDB\BSON\UTCDateTime Object(
        [milliseconds] => 1592379129885
    )
)

更新与删除操作

更新与删除依然使用 MongoDB\Driver\BulkWrite 进行操作:

$manager = new MongoDB\Driver\Manager("mongodb://192.168.10.10:27017");

$bulk = new MongoDB\Driver\BulkWrite();

// 修改 update 
$filters = ['product_id' => 103];
$sets = ['$set' => ['product_price' => 111.22]];
$updateOptions = ['multi' => false, 'upsert' => false];
$bulk->update($filters, $sets, $updateOptions);

// 删除 delete
$filters = ['product_id' => 101];
$bulk->delete($filters);

try {
    $result = $manager->executeBulkWrite('testdb.products', $bulk);
    var_dump('修改影响的条数: ' . $result->getModifiedCount());
    var_dump('删除影响的条数: ' . $result->getDeletedCount());
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
    var_dump($e->getWriteResult()->getWriteErrors());
}

操作返回结果如下:

$ php mongodb.php
string(24) "修改影响的条数: 1" 
string(24) "删除影响的条数: 1"

请使用推荐的类库进行操作

以上内容仅演示如何使用 php mongodb 扩展进行简单的增删改查操作。

如果真要再项目中使用 PHP 进行 MongoDB 操作,还是需要使用一些封装好的 PHP 类库。

(1) MongoDB PHP Library

该类库是 MongoDB 自己出品的操作类。 The MongoDB PHP Library is a high-level abstraction for the MongoDB PHP driver.

$ composer require mongodb/mongodb

(2) 如果是 Laravel/Lumen 项目,可以使用:jenssegers/laravel-mongodb

该类库对 mongodb/mongodb 进行了封装,能与 Laravel/Lumen 进行更好的融合,可以使用 Laravel/Lumen 封装好的查询构造器,方便操作。

$ composer require jenssegers/mongodb

(3) 更多类型请参考 MongoDB 网站的 PHP Libraries, Frameworks, and Tools

参考链接

https://docs.mongodb.com/drivers/php-libraries

[END]