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
    . U, [& E" m. L. S

  2. * F& M0 y2 }0 B, _
  3. use MongoDB\Driver\Manager;" E' j! ?1 q; c3 e: ?+ ^4 N
  4. use MongoDB\Driver\BulkWrite;
    7 o8 Y' Y( R! x7 D/ G1 T# {; }
  5. use MongoDB\Driver\WriteConcern;; I# [: ~- |7 J, ~0 ^2 _  `
  6. use MongoDB\Driver\Query;
    ' w2 ^# I. A( B$ j" o% |
  7. use MongoDB\Driver\Command;; e6 O  y1 n/ z; O9 D3 }& j8 ^2 z$ {
  8. 2 H4 T  k1 C. j7 A& j
  9. class MongoDb {
    - a4 |  P5 w. W, B4 r( D

  10. 8 R, N# t3 V% X  N7 \. I" u
  11.     protected $mongodb;2 ?% J3 g' S9 _3 H% V: c
  12.     protected $database;7 j% N1 Q  J4 J4 j5 R
  13.     protected $collection;
      E" W" A# O2 M% `7 a. b
  14.     protected $bulk;
    5 M: E  G1 \  ], f3 j5 W4 [8 f0 W
  15.     protected $writeConcern;
    / r8 ?0 i! l0 C4 n* |
  16.     protected $defaultConfig
    $ r2 T+ G! I$ t
  17.         = [
    . e- A1 T$ o$ `
  18.             'hostname' => 'localhost',
      [  _% f  c( @8 O: b1 Y
  19.             'port' => '27017',$ A0 @  V" C+ ]: F5 L6 ?7 H
  20.             'username' => '',
      t* A0 K- _, {% o
  21.             'password' => '',7 Q' ^3 ]" ~/ [1 y# V
  22.             'database' => 'test'
    2 \* K0 }9 ~6 p2 @8 ]* Z
  23.         ];
    ) y+ @9 a7 T9 ], F) u
  24. ' s/ R$ @* ]5 m" k' z& w% q; R
  25.     public function __construct($config) {
    & W& \4 ~4 @3 }6 v: D8 I
  26.         $config = array_merge($this->defaultConfig, $config);
    % D- ^' W6 L; w( n& Z
  27.         $mongoServer = "mongodb://";& i8 G5 g1 J8 o4 b5 m
  28.         if ($config['username']) {
    " n0 |1 u$ |: M$ b% b
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';5 i3 U4 v/ Z, ]8 n+ m
  30.         }
    & j* b( \9 u0 z  z
  31.         $mongoServer .= $config['hostname'];7 A# c+ o4 w9 r& W, [) n$ z
  32.         if ($config['port']) {
    5 j, q8 ^2 @% E
  33.             $mongoServer .= ':' . $config['port'];) Z" A1 b& l/ F; R
  34.         }
    $ u2 @9 ^6 L- l; v  x0 B% \1 B: k$ O
  35.         $mongoServer .= '/' . $config['database'];0 y2 O( o4 T$ G. `: |* Y! R  M

  36. + R5 `  w! \" f2 R& M2 Y
  37.         $this->mongodb = new Manager($mongoServer);
    3 e5 D0 b$ z$ i$ \: v3 C
  38.         $this->database = $config['database'];0 B9 R# T8 T0 Z/ d) G+ O( L; R' H
  39.         $this->collection = $config['collection'];
    2 z: J+ M, D0 f9 C( z% G
  40.         $this->bulk = new BulkWrite();
    1 S+ D0 i' e1 p% \3 I# p5 p
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
    6 F: U- j3 N! D
  42.     }
    6 i8 a1 j, i' K  R+ F% r

  43. + V  G; j) G. @
  44.     public function query($where = [], $option = []) {
    , \/ s9 Y1 U, T. z9 z: _
  45.         $query = new Query($where, $option);# O+ L6 \# v4 P- z7 l2 A  B, ?
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);4 ?' o8 Y0 m, H/ _
  47. 1 j' x0 c5 t; M& s2 t/ ^
  48.         return json_encode($result);/ t7 Z! _# R# |" C$ x$ m8 c
  49.     }
    3 \+ T! }- C% |- f% D6 s' |
  50. / ~% C! x* u' v. t
  51.     public function count($where = []) {. N; n% m% Q0 b, u7 D" r. g
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);
    + j! K0 B9 h2 |4 [. Z& o+ Q
  53.         $result = $this->mongodb->executeCommand($this->database, $command);$ o$ K) Q1 b# K
  54.         $res = $result->toArray();4 [, H1 s  |% m+ ~3 l; g4 s" i
  55.         $count = 0;
    - b( S  N2 x4 b8 C5 f- T1 n
  56.         if ($res) {
    6 P. g) [% i  T1 p* W1 n
  57.             $count = $res[0]->n;
    : D0 q9 E) R! r/ K: ~) b& X
  58.         }
    & S& c& \6 I6 f% l

  59. + v5 r+ w6 `( k& K
  60.         return $count;% f! k) _0 b9 X) X+ p5 M" A. m
  61.     }
    : |# `3 Y$ s' A7 N5 n# c/ Q) C

  62. % i: o- v6 E! P$ u& x% o( K
  63.     public function update($where = [], $update = [], $upsert = false) {
    $ g1 I- R: Y; a+ A
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);5 V5 [( M1 d, a/ h+ e
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    / y: D. Y: y3 U5 H# A/ g
  66. ' [3 I4 t0 f% E; T, r1 B
  67.         return $result->getModifiedCount();
    # h! f+ V0 ~% L0 {) E$ k
  68.     }4 {3 s8 W( P( [9 l5 |6 c
  69. * L1 e: H; _3 e: b6 M$ _" [% I* H/ k
  70.     public function insert($data = []) {, Q- r3 H; B; D6 D2 }% j9 c" K  C3 ^
  71.         $this->bulk->insert($data);
    * n5 m) \3 ?! t# ?  A
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
      P- C9 M3 t" {9 y
  73. 1 `' n# y$ G3 W: s2 J: |/ }
  74.         return $result->getInsertedCount();
    2 f! Q! B1 U. X3 R- }
  75.     }4 J4 H- O8 p0 w  y. N/ ^% E3 {
  76. ; h$ X) I+ T  _
  77.     public function delete($where = [], $limit = 1) {
    ! W# O9 m0 r3 i; z3 K  W- O  r
  78.         $this->bulk->delete($where, ['limit' => $limit]);  q) a+ H5 _- l, @" F0 _. K. H4 t
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    % R. y  V' N8 M) a8 v

  80. : ~( w! f) Q9 r( l# W# }1 r0 G% h
  81.         return $result->getDeletedCount();
    " \+ k$ N; W  h/ @; Z$ G
  82.     }
    7 O4 h$ c9 R6 r9 j. B5 V
  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 M( I1 }5 X! H2 R/ \, k
  2. $lastId = $resultOne->getInsertedId();- z# F  M8 A7 ~* l7 Z: G1 x
  3. $resultMany = $collention->insertMany($array, $options);//多
    ! g1 r  w6 |5 o+ w
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    " o& D+ @1 @" P( ~' i" y& i
  2.     '$set' => $values1 x* t1 L, R- C
  3. ,[0 |& }1 N0 M' h& t
  4.     'multiple' => true//多条,单条false" }1 p" o6 y! p6 y- \
  5. ]);
复制代码
  1. $collection->updateOne(3 C# }5 t+ e! B5 G( s
  2.     ['state' => 'ny'],9 k3 y, f( }6 e* |
  3.     ['$set' => ['country' => 'us']]
    3 l! ^4 g4 z$ R1 d! W& b1 K
  4. );
    + Z1 h" [0 V& U+ w' p7 e
  5. $updateResult = $collection->updateMany(2 J2 T5 W# t, W
  6.     ['state' => 'ny'],
      b0 |' W, W7 \# [& @' V- N5 b
  7.     ['$set' => ['country' => 'us']]4 l3 d2 \# Z1 q9 L( `8 Q  I( Z& \
  8. );
    6 c) U) B6 F* p: l/ a
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    / \+ @, b  q. X- C" ?# W3 O- }4 }$ q
  2.     'name' => true//指定字段$ M% H- w5 M1 p& S4 W
  3. ]);
    6 S3 i- q+ q& c" ?
  4. $cursor->skip(5);
    6 [9 T9 X! r% q: `5 v9 Q4 [
  5. $cursor->limit(5);
    . S& R- P. h7 |
  6. $cursor->sort([
    : W1 R3 S( v" m2 D% Y* ~! R
  7.     'time' => -1
    # x* Q( [# W. [) X
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [) U* _8 ?8 U0 _8 }  f
  2.     'skip' => 5,* x1 d- M8 k' M. N0 b
  3.     'limit' => 5," {! e& R4 ~! i! a, Z8 x( l
  4.     'sort' => [! b7 Y/ \) T) f* p" v7 y
  5.         'time' => -1. z) u5 p4 Q% C. ?- S0 o
  6.     ],//排序% M" O$ w) C5 q9 I3 s0 Y
  7.     'projection' => [
    ) P) r6 o$ ]4 u2 M5 m
  8.         'name' => 1//指定字段5 |. j. H  a7 ], z# _- k
  9.     ]" \) f0 C7 v. B7 e* U. g4 n
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    8 }3 Y* I; P8 i/ l! j8 Y
  2.     'justOne' => false//删单条7 A- Q9 X' J/ I' H3 g) s" Y
  3. ]);: s, l' v6 \, C
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);) a# V8 X, x5 F9 _* v
  2. $collention->deleteMany($condition, $options);
    6 z  q& g% J* f

  3. 3 |- w. ]1 U4 T+ l3 Q6 \. V6 k* e
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    # F4 c: v: t6 L0 b" m
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键. W; ^& j. N& d  m- \0 \( y9 }
  3. ], [* b. L0 ~5 s3 U$ i  g
  4.     '$inc' => ['id' => 1]//自增. N! s3 O6 n9 {( y# m7 y
  5. ], [$ X) M* h- {$ E! Q- i. ]5 J3 t) @3 k
  6.     '_id' => 0
    5 i2 V+ `8 F# q) u
  7. ], [& {6 K/ ?# q$ ^* ~! s! p
  8.     'new' => 1//返回修改后的结果,默认是修改前的* Q8 }' S3 w. A7 D" A$ c
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    % g( h3 X0 Q/ A+ K1 Z8 ^
  2.     '_id' => $tableName
    : J& g! x5 b9 S& V
  3. ], [
    - U- B6 @/ }3 j# n2 y7 o0 ~
  4.     '$inc' => ['id' => 1]" @5 e6 Q8 T) h. v3 M( H; i
  5. ], [
    . Z3 l( J/ M0 x
  6.     'projection' => ['id' => 1],8 W- ?/ a& ~' }
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER+ t7 _" |4 }. V# `- |4 j
  8. ]);
复制代码
+ t$ r; _. b  _' }' w& q6 y; O2 I

% \& s  c. o4 C




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