cncml手绘网

标题: 升级PHP7操作MongoDB [打印本页]

作者: admin    时间: 2019-3-19 14:24
标题: 升级PHP7操作MongoDB
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。
详情请见官方手册:http://php.net/manual/zh/book...
但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。
详情也可参见官方手册:http://php.net/manual/zh/set....
在这种情况之下,MongoDB 官方忍不住了,为了方便使用,增加市场占有率,推出了基于MongoDB 扩展的库:https://github.com/mongodb/mo...
该库的详细文档见:https://docs.mongodb.com/php-...
MongoDB 驱动
如果使用原驱动的话,大致语法如下:
  1. <?php& ]# k, \/ E* O, L2 }

  2. . n6 u" b* n( A; g2 y/ {; [/ Y! k
  3. use MongoDB\Driver\Manager;
    6 j. \+ e) u& T, N
  4. use MongoDB\Driver\BulkWrite;) G1 N3 O# s0 \% l
  5. use MongoDB\Driver\WriteConcern;
    5 [1 v& w- q% |9 W" q; Q; B
  6. use MongoDB\Driver\Query;7 y& N9 y8 t0 t( V0 A% n
  7. use MongoDB\Driver\Command;
    7 P, j% ?' a% L$ n0 ]+ C/ P- }
  8. ' F) J$ R& V1 m2 _8 S6 c
  9. class MongoDb {
    " `: ?% x/ v. {5 ~6 t5 U6 u
  10. * s+ G2 y% \8 t( ^2 m) E
  11.     protected $mongodb;' Z, O" k# a2 X% Z3 N' O0 h
  12.     protected $database;! ^; A1 |- @' e! |7 v: a$ T, H
  13.     protected $collection;& {/ |( \- j3 W# c4 R9 g
  14.     protected $bulk;! x4 m* o4 g5 t) f  R% t
  15.     protected $writeConcern;. \8 K' C" R6 S0 X# }- M! z% h3 W$ b0 c
  16.     protected $defaultConfig
      L- B: h+ \; C* y5 F
  17.         = [
    , @* m) P* T# i; l4 m! `
  18.             'hostname' => 'localhost',
    ) E5 Q" \6 T/ ^' n- c
  19.             'port' => '27017',
    5 K# \2 C7 n% l# a1 q; n
  20.             'username' => '',/ }; K4 O) ~9 P4 l
  21.             'password' => '',0 r& e( U( U$ I1 [) c
  22.             'database' => 'test'
    $ i* o! g! d' ]5 n
  23.         ];
    9 q% z$ w; g2 Q6 u6 b: l/ {

  24. & @! Z: _2 U! S
  25.     public function __construct($config) {  A% z3 m& e! N4 ]2 H3 e5 c
  26.         $config = array_merge($this->defaultConfig, $config);
    . e; i, M5 F; m0 j6 q4 J
  27.         $mongoServer = "mongodb://";
    1 ^/ `' S3 v; q- |
  28.         if ($config['username']) {  l. G/ I" w. l* z8 P( U
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';- v+ c. C( W2 |( u; U- Y% w
  30.         }0 t& y% L, P4 E
  31.         $mongoServer .= $config['hostname'];
    : l: |  B6 _" `' O
  32.         if ($config['port']) {
    ; @4 s2 l3 t" D  Q  \" e
  33.             $mongoServer .= ':' . $config['port'];
    ) _. F  |# l  @
  34.         }
    ' T+ A' o& F/ f3 b% k' T
  35.         $mongoServer .= '/' . $config['database'];
    ( |7 ^' G* K1 w
  36. 0 `4 ^+ W( C/ a4 t: F5 J
  37.         $this->mongodb = new Manager($mongoServer);5 A. c/ O3 j. f# O8 X+ q) r$ F( E
  38.         $this->database = $config['database'];
    " e/ W7 n/ H1 S* `
  39.         $this->collection = $config['collection'];. J( J. L& k# t" ?9 e% K
  40.         $this->bulk = new BulkWrite();5 u* Q- W8 F& f* }- W
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);/ x+ [* ^0 Y# `+ U" \/ [
  42.     }
    ' @1 v( S2 q' f! q, \' t

  43. * b  [/ O) F6 r* W: ?) E) v! r
  44.     public function query($where = [], $option = []) {  ?) c- Y% [/ i3 w2 ]
  45.         $query = new Query($where, $option);3 z  E5 c# ], N
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);; H* Y+ N5 _& w! c5 v, z, P0 a

  47. 1 B) n% \' B9 T* m. r8 W
  48.         return json_encode($result);6 I* R0 b$ y# ~0 `
  49.     }
    ) G9 Y5 s' Q% C& T% o* k

  50. ! \" X" j* L" A. C) S
  51.     public function count($where = []) {: Z. v2 A% j& ^; S9 X# k# o
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);& V4 r# a7 l6 M: Y9 F6 G3 R  R& d
  53.         $result = $this->mongodb->executeCommand($this->database, $command);6 a, y8 I* n: O' b: q
  54.         $res = $result->toArray();1 Q) L# q) S% n+ [: C  r
  55.         $count = 0;8 x5 W/ t) E* t5 E8 Z% D# g
  56.         if ($res) {" V+ h1 O) y+ _+ L  ^, C) p
  57.             $count = $res[0]->n;
    0 M( P. m8 r+ R9 d0 c  m. V3 E
  58.         }
    4 f& ~, M! K( z' X# L% Y; P* H+ I$ y
  59. 7 v1 Y. \! j4 t" b4 M, o
  60.         return $count;
    * A/ ?9 z1 @) i& j+ `
  61.     }
    # c! j' o  k# Z8 K( j2 o5 O7 X; `  [
  62. 2 n6 e# Y& O+ T7 k+ @1 q
  63.     public function update($where = [], $update = [], $upsert = false) {
    6 i3 @) ?- f8 E' U% I( A( S
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
    2 L4 `3 d8 U+ I
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);$ F* _" F% l. A5 n# L  `3 y
  66. 6 j( o  Q8 T+ ]4 v4 X  d
  67.         return $result->getModifiedCount();
    - F( \' q0 M0 n4 p0 Y( c% p
  68.     }" ]5 j; }. P: y2 D- e7 ?4 ]1 K

  69. 5 g- x/ {) h$ Y" W$ T2 e2 r
  70.     public function insert($data = []) {
    % i) q! ~. E( w$ X- k
  71.         $this->bulk->insert($data);
    " u1 t" K4 t* O  r& C2 `6 P
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    , J# }5 `2 e% m  r
  73. ' l! R& }" j7 F2 Q2 z4 l
  74.         return $result->getInsertedCount();. J: [9 @# U' |7 O
  75.     }
    3 i. |. D( T& k$ n
  76. ! Y+ i9 L  \9 _+ d" O9 s# a
  77.     public function delete($where = [], $limit = 1) {
    - |+ Z5 S  E9 ]$ \. N# y
  78.         $this->bulk->delete($where, ['limit' => $limit]);
    / Q4 Z2 k: t5 B; |  M
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    , }/ k9 x0 I& h& m7 A3 O, J
  80. , H1 P' M: e) @$ ~' a
  81.         return $result->getDeletedCount();  @; @4 H* T, g5 e4 E* F" w
  82.     }
    : U& T# _2 ?0 O) g' u. K  M
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单7 n' ^  o" G8 B# U# W- w4 z
  2. $lastId = $resultOne->getInsertedId();
    ' S6 D! {, ~, D
  3. $resultMany = $collention->insertMany($array, $options);//多7 S9 t, f# h/ E
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    ; |+ q4 l' C. h
  2.     '$set' => $values& E2 D6 `$ K7 y$ M0 Y7 Z
  3. ,[, \' i, Z' j1 g1 q" l
  4.     'multiple' => true//多条,单条false- N  h5 `0 ?  \5 Y$ t
  5. ]);
复制代码
  1. $collection->updateOne(
    / X, S5 w3 Q$ D- s% q
  2.     ['state' => 'ny'],$ k5 J- o/ O  ?2 S, a
  3.     ['$set' => ['country' => 'us']]
    $ c' ~* _8 G' H
  4. );
    & v0 g& E) Y/ i  e" C3 `( f' p$ @
  5. $updateResult = $collection->updateMany(
    ' g) [+ B7 I! @% i$ D) K" t
  6.     ['state' => 'ny'],
    8 F0 D9 ]; J2 G9 q
  7.     ['$set' => ['country' => 'us']]
    8 P4 P: M5 }8 j7 u4 r3 X
  8. );
    8 q+ ]  v& R, W
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    # k' u* @: s' W& f. k
  2.     'name' => true//指定字段, t2 c; K: h' v+ D' v& Z
  3. ]);2 p6 B, v$ w4 E9 N; t) P' v
  4. $cursor->skip(5);7 }& q7 Z" O+ A) b& Y
  5. $cursor->limit(5);4 o' R1 ]9 {3 x. D
  6. $cursor->sort([
    7 l3 R' l$ c, y# D! G6 i  c$ C" [- k
  7.     'time' => -1- \# Y; `2 e: t" E  e3 p
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [- \9 _# _3 v! l) G
  2.     'skip' => 5,
    / j* X. f$ Q  n# X: M
  3.     'limit' => 5,
    : N, X1 _# A) W
  4.     'sort' => [' p. p/ l0 S# V# N
  5.         'time' => -1! k7 V" G- j# }1 B  k- U$ a3 m$ W
  6.     ],//排序
    % [. D6 ~" t  [
  7.     'projection' => [; {$ A3 |5 I" l7 J
  8.         'name' => 1//指定字段& a8 U# n9 w" C/ G- }7 c" f
  9.     ]
    0 ~! V7 M1 C8 f. p, h
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    " C5 m% `" D2 N+ p3 J: Y
  2.     'justOne' => false//删单条/ o* ?2 h! S5 o  ^
  3. ]);
    / x) M; b8 Z8 d
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);
    , }3 I1 l5 g' ?! ~
  2. $collention->deleteMany($condition, $options);
    ' M& N/ u0 {- g2 ~
  3. ! R$ p. ?% ~* d: q2 }* n/ C& e- Y
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    5 \. {1 I1 }; z* O, u
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    * l7 R7 O# Z% ]- N* M
  3. ], [
    . X. K6 R) z9 p
  4.     '$inc' => ['id' => 1]//自增
    8 r9 k, r/ T8 f8 ?' X. w
  5. ], [3 |' g- c1 c! J% S  J2 x
  6.     '_id' => 0$ w* G. x. }+ S2 C
  7. ], [' X. R, p2 E! ]4 N
  8.     'new' => 1//返回修改后的结果,默认是修改前的0 M6 X9 X$ Y. t1 a0 f
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    ' z( U% A" g  c/ f; i+ O- V7 X3 x
  2.     '_id' => $tableName5 q1 W! x* y2 @( [/ C
  3. ], [" i, ~, T( o- u7 }- v6 r' Q( {
  4.     '$inc' => ['id' => 1]9 [9 X2 ^4 V/ O. H- |' T" G
  5. ], [
    4 `7 I% T) X- d6 ^- L+ b
  6.     'projection' => ['id' => 1],
    1 I1 b+ b/ Q' m% p
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER% h! V+ r1 |* d3 `1 u5 m' J
  8. ]);
复制代码
  y. E0 ]* H$ M$ U

- y) W9 R/ {' }2 l




欢迎光临 cncml手绘网 (http://bbs.cncml.com/) Powered by Discuz! X3.2