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
    ; j* D- w! o- w' j7 `
  2. ( f* n5 y/ [! G& }+ Q3 T/ P0 Z
  3. use MongoDB\Driver\Manager;
    ' D+ y- X8 J* S8 Z* u) l  A$ R
  4. use MongoDB\Driver\BulkWrite;
    . t; K- [* f: P9 `7 `
  5. use MongoDB\Driver\WriteConcern;
    ' X' _  y8 y* Q" G$ n% v; A
  6. use MongoDB\Driver\Query;# M- z* e/ A) H4 J1 F: Z* Q
  7. use MongoDB\Driver\Command;, p9 I4 e0 X& C& `7 z% u
  8. 3 k. ^2 O3 \8 z4 A
  9. class MongoDb {0 i. c, p) u' s

  10. 8 v- t% S# E+ g8 ?4 I4 y2 ]4 g
  11.     protected $mongodb;  M- j0 ?3 J$ H
  12.     protected $database;
    7 V$ x% m+ P+ |5 D
  13.     protected $collection;) J9 P" F9 S9 i
  14.     protected $bulk;' Y3 ^- }9 l/ _, e
  15.     protected $writeConcern;
    ( t: y' {  c$ W& Y7 r4 L7 @" l
  16.     protected $defaultConfig2 \6 [- y' }4 J% |3 A
  17.         = [: R- y, B$ W0 }. s
  18.             'hostname' => 'localhost',% H/ J6 _" V# ~( K- {, j  v; v
  19.             'port' => '27017',
    ; v" B# g- ?! f
  20.             'username' => '',
    8 z  k. H+ K5 s9 T
  21.             'password' => ''," g6 y8 A! S0 Z7 Y, C* u3 G3 z
  22.             'database' => 'test'
    . U$ Q2 H- o4 f/ o4 n; Q; P
  23.         ];( a8 x: k& A3 p; ]6 E

  24. ' O; D% g& _- U$ j: [
  25.     public function __construct($config) {1 `7 |- L* Z) A/ b7 Y5 n
  26.         $config = array_merge($this->defaultConfig, $config);  Z8 B7 n* @, J1 v
  27.         $mongoServer = "mongodb://";
    ( D% W7 w& q7 f3 @; k, Y/ i* J
  28.         if ($config['username']) {2 o" j( b* f, I$ S
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';9 S9 p! w9 ]) Z$ m3 ]& w
  30.         }
    . w( S  |, ~3 k( A+ j, X
  31.         $mongoServer .= $config['hostname'];
    ; C, x7 ]. d  f" q- \! w9 Q  \
  32.         if ($config['port']) {5 v1 ^  `& {3 s( g6 ^$ n3 h
  33.             $mongoServer .= ':' . $config['port'];6 p3 m5 @7 W% z  z
  34.         }* [( A5 m% G5 K) o! P1 j
  35.         $mongoServer .= '/' . $config['database'];
    4 }& U; t4 R9 K- f

  36. 6 J7 H  }) C: F$ C
  37.         $this->mongodb = new Manager($mongoServer);$ X9 Q- J4 i! o" }' |( x; }) Y
  38.         $this->database = $config['database'];
    # I& I1 s6 R4 w1 n1 Y
  39.         $this->collection = $config['collection'];
    * h$ r% }# \; [4 O7 b; z
  40.         $this->bulk = new BulkWrite();
    # {7 i: b4 J6 Y, [  k
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);' Q1 L1 o' O+ {: A5 r! D5 _0 o' Q2 D
  42.     }
    " D3 v$ r/ S5 ?( Q  b
  43. , V& h3 r, Z) L- H* I
  44.     public function query($where = [], $option = []) {9 s' B7 D7 i4 j( m  c1 U
  45.         $query = new Query($where, $option);) m: x. c& o* U$ b' x0 R7 Y% _3 I9 |; H
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);$ B" q% g- y# y0 U

  47. 2 o& a" x2 M: G! W" k/ Z2 q/ e
  48.         return json_encode($result);" ^4 D0 N; p2 z; x  B& p
  49.     }
    4 ^2 F- M% O6 O! |& j, R
  50. 6 Y3 o/ s4 b+ r
  51.     public function count($where = []) {1 j3 {, H9 b( V' E2 P% I* B, a
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);" F. D* o' q7 O
  53.         $result = $this->mongodb->executeCommand($this->database, $command);
    . T! t/ r0 y0 q& n- p/ r- d
  54.         $res = $result->toArray();
    5 C8 v& E% a% B" c" n% h7 U
  55.         $count = 0;, ~2 M0 Y* \6 t# ^2 W6 E
  56.         if ($res) {( f6 r6 m1 |" B) Z5 g" m' F
  57.             $count = $res[0]->n;6 g9 \' v/ d5 n# k4 U
  58.         }
    ' F; @. E& G' a
  59. . ]% K5 x7 F6 u- f+ p3 A0 O
  60.         return $count;8 m* X, m$ C, P: j5 a
  61.     }
    / H* C- h3 o# k% {0 h( i! O9 m( I

  62. / i; k( ^& `9 a% {- L
  63.     public function update($where = [], $update = [], $upsert = false) {) g, ^( q% p) _4 W; b6 C
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 c. _/ n/ S' W( `6 y/ N3 ?: h
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    . T2 ?( G$ w% x2 N0 a

  66. " G5 m8 i/ ?& w, q, X* S/ M: {+ v
  67.         return $result->getModifiedCount();
    ' c+ }) K& X5 G2 {0 y+ ^1 P6 |6 y
  68.     }
    5 \" Q; p! ?1 S% ?- b

  69. $ H8 @/ G. V6 s  F; N  N" J. Z
  70.     public function insert($data = []) {
    1 y, e' @# Q- j, y4 S4 j
  71.         $this->bulk->insert($data);
    0 V; ~' ]! {* R* D7 C  z
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    * }' B9 b$ e2 o

  73. 2 C: g  v" y) y' F1 I. E! L7 \  v0 l
  74.         return $result->getInsertedCount();7 T+ v% O  r8 }- t9 ?. c# s
  75.     }( @& K% T% s+ f; H0 k
  76. ( Q; f; k  J# O2 ?3 i, c
  77.     public function delete($where = [], $limit = 1) {4 @, a! n/ @' ^/ I/ |
  78.         $this->bulk->delete($where, ['limit' => $limit]);
    ! f9 t1 @: o' O1 Z' X6 }
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);- q" c0 i8 G( i5 C5 d* D8 c
  80. # R# g; W- W9 e' z9 l% P5 B
  81.         return $result->getDeletedCount();3 E/ P: {% x  p0 C
  82.     }, _+ G2 P+ y. W
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单
    ( E# \3 D, v! z3 X2 ~
  2. $lastId = $resultOne->getInsertedId();
    , V) \5 d% o  S6 s
  3. $resultMany = $collention->insertMany($array, $options);//多6 Q* o! D% Q1 m* J  F; U7 A  Y# ]
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [6 i  v6 \, u- p: ^: T4 s- V
  2.     '$set' => $values
    5 U7 Y4 Z) u( f7 c, k7 E, S
  3. ,[  q) }  |, o) ~7 _% Z
  4.     'multiple' => true//多条,单条false! q. N& Y3 {9 ~- ~) P' S
  5. ]);
复制代码
  1. $collection->updateOne(
    # f/ N: y4 W" l2 x4 K
  2.     ['state' => 'ny'],9 B) F7 S" D! |6 Z( ?: W( T
  3.     ['$set' => ['country' => 'us']]+ W% `' }8 l1 ^6 W
  4. );- W* L! Z5 n. n0 G6 n
  5. $updateResult = $collection->updateMany(
    ; G* i$ ?" i7 v& B* I
  6.     ['state' => 'ny'],
      _, \) Q1 S+ d
  7.     ['$set' => ['country' => 'us']]' j. u; k0 V8 E: A# n8 [  s! X
  8. );
    ! t+ Q$ t" v# y  |# h6 \
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    ! e4 y5 N$ @% l! f
  2.     'name' => true//指定字段: E0 S6 [# U. ?. B5 h
  3. ]);2 V, ~" A2 \& s6 M5 L1 B0 e
  4. $cursor->skip(5);
    & m" J, Y% K2 M; i) q
  5. $cursor->limit(5);: Z5 b$ z0 N; x+ G- v
  6. $cursor->sort([% d. h) X, O( Y' |" r
  7.     'time' => -1  u% R% @% H9 h/ ^( Q, U# q# u
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [( U$ z6 a2 ^& w& X3 n5 ~) _, u8 k9 e
  2.     'skip' => 5,
    / b4 \  S& q4 e4 R/ b
  3.     'limit' => 5,# y! n8 D0 L: L2 u* @
  4.     'sort' => [
    0 o: l! p1 q- k% }5 B6 M, f
  5.         'time' => -1
    ' }+ g7 L, y) p3 i9 N7 J- D% g
  6.     ],//排序
    0 g6 I" U& \  X+ m
  7.     'projection' => [
    - w  u+ \8 k! ]0 F) a
  8.         'name' => 1//指定字段
    . k" I3 V0 _6 d5 P
  9.     ]
    6 M+ u- n* D, G0 i/ ?
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    1 d# U+ [' p# E* ~* V" R' N
  2.     'justOne' => false//删单条1 N$ m; f6 I8 i2 H
  3. ]);
    ) }. u: N# d6 u3 s! |7 L- U
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);
    0 n# p, g  U$ o: e1 B4 O9 ^
  2. $collention->deleteMany($condition, $options);$ I- K' `  {. q/ S

  3. 3 m, R* v9 j* I2 B- H5 L) k
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([% b6 z6 A0 K! ]2 O- A) W) U+ L" b
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    : X1 z# I& M- k
  3. ], [3 S- c" j: N( G% J
  4.     '$inc' => ['id' => 1]//自增" f+ ?: l# j2 R+ b
  5. ], [
    8 r$ F) ?( a, y, S+ F! J
  6.     '_id' => 05 _% m# ~* m0 L2 z, |
  7. ], [
    + m2 d4 w' B/ {8 i9 n; w
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    5 G! k6 A! g' V1 n& c/ [
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    ; t  G& P8 V3 L" y, ]7 A
  2.     '_id' => $tableName
    : `9 [' d5 u" V! ~6 t
  3. ], [
    ! p. b# }  A% g! Q( \) t
  4.     '$inc' => ['id' => 1]
    , P* S- }- a  |4 a
  5. ], [' c. K" i& g# Z% ^; `& w
  6.     'projection' => ['id' => 1],  J$ i; I  G; E4 b5 f& C
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    ; a0 Q5 N( R7 x, Z
  8. ]);
复制代码
. o7 z' j0 Q- B+ E4 |6 a, C
* y& H- |2 L8 y2 m% b6 e. T





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