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. <?php0 |1 t6 ]" N* H6 @4 x0 N. i

  2. $ x* k4 f9 c* ]; Q  P: k: Z) g
  3. use MongoDB\Driver\Manager;
    0 v4 R2 _  [- h* C$ y
  4. use MongoDB\Driver\BulkWrite;
    * B5 x1 M( D3 b# P1 E$ Y
  5. use MongoDB\Driver\WriteConcern;$ C. }4 j0 O5 O3 H2 t! ?5 p/ f
  6. use MongoDB\Driver\Query;
      \) C, @" u0 h# u4 C' t( `3 u  e/ i2 R
  7. use MongoDB\Driver\Command;8 W$ o; {& l! w, ~6 ^( z0 v- a( t

  8. ) q' d2 S/ J9 W
  9. class MongoDb {# h4 |  I5 C" V& x7 O' d- H
  10. ( ]. K* C4 @8 y' i1 S$ v& X2 g! S5 Z
  11.     protected $mongodb;9 a/ i* P3 I2 y( y
  12.     protected $database;  u+ P$ A- g  }" `
  13.     protected $collection;& E5 G( E. q% ~- q
  14.     protected $bulk;
    # F; H* {. v3 {* X. h
  15.     protected $writeConcern;3 d- v2 j9 Y, F; h( p' U' F
  16.     protected $defaultConfig
    4 m8 O5 m. ~" x( f! H2 }  @
  17.         = [
    % v; C: |3 q. G1 w/ K
  18.             'hostname' => 'localhost',
    + b3 V* K/ ~1 T% O; n, ~
  19.             'port' => '27017',! Y  w* S: ^1 D; \# l; P
  20.             'username' => '',
    " Y$ q1 Y4 g# _& q5 x
  21.             'password' => '',
    2 x, X1 P3 P( v
  22.             'database' => 'test'
    $ b' T, W5 j5 D% u/ {6 X) S
  23.         ];
      r& V4 U) _/ U. T7 M

  24. 5 V- r- A* B0 S* m4 _$ U- ~* u
  25.     public function __construct($config) {
    2 d* c& P5 k& Q0 {/ u& I; t
  26.         $config = array_merge($this->defaultConfig, $config);
    ( B4 ~7 h: e' F) Q: ?. D
  27.         $mongoServer = "mongodb://";
    " B, J; Q# ~2 C! s  s( h: P
  28.         if ($config['username']) {
    / f% F, M: I; H/ V' S4 k
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    2 P" c, `; q; m' t7 n+ j4 e# w- n
  30.         }
    ! g. F. B- Z8 t2 Z% m9 \
  31.         $mongoServer .= $config['hostname'];% s4 x. A: _1 p6 n) M
  32.         if ($config['port']) {
    8 |  U. i/ M4 U+ C! y1 r, d
  33.             $mongoServer .= ':' . $config['port'];
    ( E3 e* w6 Y" _( E! v0 C7 H  @
  34.         }
    7 l0 m) u8 T5 d/ d7 A. S
  35.         $mongoServer .= '/' . $config['database'];
    : h, h5 q6 s6 l' u2 U

  36. 1 k  `5 q7 r8 e/ r' X: `: L& c
  37.         $this->mongodb = new Manager($mongoServer);
    7 n* `& W2 T" v, h
  38.         $this->database = $config['database'];; {7 o+ C4 D5 s
  39.         $this->collection = $config['collection'];" c9 ~. ?3 h# K% W- d
  40.         $this->bulk = new BulkWrite();% d8 s" k8 J6 x( O: ]( h' t  Z5 D
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
    : W  l2 C6 d- n% U6 t1 Y9 l1 m
  42.     }" l# Z* Q6 N% K4 ~- Q+ M

  43. & s# w8 W' D0 V8 h# `1 X
  44.     public function query($where = [], $option = []) {0 V, P& a5 T) g7 J9 p7 T+ j! l8 i
  45.         $query = new Query($where, $option);+ M2 c; t; E3 @/ R
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
    - u! g9 v9 U; ^& Q: c

  47.   k+ w* u) f" }( S
  48.         return json_encode($result);- \+ E0 |2 R; K7 ]6 [
  49.     }
    & L: M8 g* g* h5 u0 }) ^/ ?; L
  50. : @& {3 `  o0 a: g. C- y( Q1 [: L
  51.     public function count($where = []) {; }. u( E$ i& f- t
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);8 C& W% P/ K; ?- W
  53.         $result = $this->mongodb->executeCommand($this->database, $command);3 |- l" I2 p! j2 n8 }9 [
  54.         $res = $result->toArray();; J; w' Q( u' u
  55.         $count = 0;& N  o4 v; y# t
  56.         if ($res) {
    3 s, `  M) x7 P/ z
  57.             $count = $res[0]->n;" c. j6 y7 k0 D8 b* y
  58.         }- V9 Q6 L6 N2 p! Y& A
  59. 9 I- u, u/ p  m! i' \
  60.         return $count;
    " ?9 f% I9 u8 Z3 G' }% U
  61.     }! ]% t; M9 H+ e
  62. - O2 t1 ^: B; M& G
  63.     public function update($where = [], $update = [], $upsert = false) {$ R- m8 `& k; v& f: x# Q% c& j
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);7 ^/ R$ z6 s- Q" v& S' D: E
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);: b- V6 r+ K3 p( q

  66. # k, U  c: @- D. a
  67.         return $result->getModifiedCount();
    / J# d  X- T! D) P* r3 _0 s
  68.     }! ^$ A. p9 D1 z7 Y& F9 C
  69. ( j, p4 [; e# q3 [+ E) M6 q; i
  70.     public function insert($data = []) {
    4 F3 L4 {" r' Y  z/ L) a6 B
  71.         $this->bulk->insert($data);
    ; @- p8 {) l7 X. Y5 D; P. }. U
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    * G1 m8 M/ [$ e# D6 y$ {3 i
  73. " L9 _% }# d; {- n/ L( |# k9 R4 c8 Q. J
  74.         return $result->getInsertedCount();5 e% e* R- g8 H& W* ?) \* J
  75.     }
    + I8 }& o5 f* _9 Q
  76.   r4 @% N; j8 f- n7 O
  77.     public function delete($where = [], $limit = 1) {
    4 r2 y6 z# i, O
  78.         $this->bulk->delete($where, ['limit' => $limit]);% }5 v: T6 F" |
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    4 S9 |/ S: ?4 ^- @- x, Q

  80. 4 \1 x  h5 Q% F7 Y3 R* t, L2 m- E
  81.         return $result->getDeletedCount();  @) @$ B3 Y% n" N/ K; D) s
  82.     }+ N' }! v* _/ q% p0 r% E$ x
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单
    # s: @7 Q& e6 J
  2. $lastId = $resultOne->getInsertedId();$ q; G2 |0 e4 x4 e" o$ h
  3. $resultMany = $collention->insertMany($array, $options);//多8 O% N; x+ l1 a! R5 Z( n; Z& c
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [! K4 f* n2 H/ G! }( J" }: ~" h  _6 s
  2.     '$set' => $values
    ; X' Q  z3 D! U6 m9 |
  3. ,[4 S3 J0 V* E$ w3 c
  4.     'multiple' => true//多条,单条false6 b+ q. F0 Y* [+ a3 S8 h
  5. ]);
复制代码
  1. $collection->updateOne(5 _8 y3 `; b! P( b2 u
  2.     ['state' => 'ny'],
    9 g; W. x% v; T( B" U4 f' _" y/ O
  3.     ['$set' => ['country' => 'us']]% H( J( K/ i$ U: R8 B
  4. );7 }$ o% ^( i1 z% C* t( j
  5. $updateResult = $collection->updateMany(2 p. [9 X3 M, P, L: f
  6.     ['state' => 'ny'],
    ! u% H) d1 r6 y3 q
  7.     ['$set' => ['country' => 'us']]
    8 b( F/ C! K6 p
  8. );1 e) x: {. z: Z; Z4 {5 D. t
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    / v! D6 {6 u! s! [
  2.     'name' => true//指定字段
    , r& x$ S' _4 P
  3. ]);3 ]. Z) s+ ]; s- p/ B; f% w0 Z
  4. $cursor->skip(5);
    , j! Q: I4 ?) I- X
  5. $cursor->limit(5);  Q# `8 h: E& x
  6. $cursor->sort([
    , u+ S5 k1 M5 `5 f* j) b. P
  7.     'time' => -1! B9 d; q, f: S$ w+ u0 u
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    7 Z) }$ w( ^/ o3 X  }! U
  2.     'skip' => 5,8 z% R& D4 W* `/ V
  3.     'limit' => 5,
    4 Z! X% n5 `& M# C
  4.     'sort' => [
    ' S2 Z/ ]- t$ q2 }* j
  5.         'time' => -1
    5 e* u0 ~) R: O3 y4 `; O5 D4 P0 X( u
  6.     ],//排序/ H' _  e2 Q7 T1 N
  7.     'projection' => [7 T) a1 \- z9 ^0 i/ i. Q
  8.         'name' => 1//指定字段. a7 |+ `% S5 a9 `( j' q. t
  9.     ]
    ' W/ I3 a1 v6 ^: o
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    6 X1 Q: p3 U+ X8 K7 i. u+ ^) f
  2.     'justOne' => false//删单条
    * F# P; Z. Z% h) j* l! ]
  3. ]);
    1 O" v/ ?9 C3 R9 {
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);& S1 W2 e9 V+ z, H6 w1 x
  2. $collention->deleteMany($condition, $options);$ x8 L* Y; x' z9 T2 q
  3. ; J7 w2 n6 J6 w, B$ j9 C1 L- |& _
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([' `: @5 l' T& @, ^
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    9 R/ ^% x  L  w& b, p2 b
  3. ], [! Q9 d$ I7 X$ e7 `8 A
  4.     '$inc' => ['id' => 1]//自增
    & w0 k$ m% v3 }7 Z5 b; z$ [2 t/ v
  5. ], [
      J& [" o2 J: b! x$ i& L
  6.     '_id' => 0
    # z& A3 h9 z1 ?; q. z' a
  7. ], [
    ! S4 Q# f$ s, i- d7 @0 _1 @: J3 u; Y2 }
  8.     'new' => 1//返回修改后的结果,默认是修改前的( I5 n% `1 B2 j- `: I
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([0 o4 q& t( ]4 P1 t
  2.     '_id' => $tableName
    - F/ d: |4 b& b2 h# h
  3. ], [' P! ?, H4 M* P
  4.     '$inc' => ['id' => 1]; Q, z; k2 \' l9 f' L
  5. ], [& n4 q: ]# b5 T+ L* K
  6.     'projection' => ['id' => 1],
    , T- R8 J- j! P6 I4 G# u+ O9 d) S# c# R
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER$ _# J8 Q* i2 U& e5 z
  8. ]);
复制代码
  o. x; B) ^" f0 d, Y3 T" f' U1 @

8 r$ A7 R( k3 ]) x: E




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