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
    ; e, N  B% r" r3 e7 J

  2. 1 q% U) S! F/ Y2 f. Q
  3. use MongoDB\Driver\Manager;
      g9 P! J/ ?# Y9 T: D
  4. use MongoDB\Driver\BulkWrite;
    # a& ?' h& `5 N$ _+ }$ J
  5. use MongoDB\Driver\WriteConcern;- m5 X" Q' w/ t) X8 o# ?# B% y' w! `% O
  6. use MongoDB\Driver\Query;
    8 W0 l3 F% ?  w+ o
  7. use MongoDB\Driver\Command;
    0 t% w; ^& W, i# b# A  n' Z7 [
  8. 6 D+ }6 V4 a; S& e
  9. class MongoDb {$ U8 \  ]+ x7 p3 ]- S  p

  10. 5 {' U$ E# G. h
  11.     protected $mongodb;1 ]& J0 d1 V" |" T0 f3 N4 b! v
  12.     protected $database;( U3 s/ {2 r0 E$ T2 x! l. d0 I
  13.     protected $collection;& ?  k9 I5 ?1 y1 Z7 ?
  14.     protected $bulk;. V; L) L+ i! l  r
  15.     protected $writeConcern;: M! _0 I$ p4 \9 e; h
  16.     protected $defaultConfig7 P8 n9 Q# q) U! w- P  |! L
  17.         = [
    ( ~6 b% H+ w. x- U8 l* Q
  18.             'hostname' => 'localhost',
    - X5 c' @5 i  F- R
  19.             'port' => '27017',
    5 _6 d. f5 H: Q4 T
  20.             'username' => '',
    : h# }$ ~. n0 P/ u( Z
  21.             'password' => ''," X( _. s# |7 g9 \/ n* w5 V
  22.             'database' => 'test'
    7 K6 N" a  }, y. j# N- x$ N
  23.         ];
    8 \1 d/ z9 |" Q  o, \
  24. ( T  u' ]4 a& {( |# f8 W
  25.     public function __construct($config) {
    3 G. `! m: H# h7 \% O
  26.         $config = array_merge($this->defaultConfig, $config);
    1 ~5 X: ]0 `. o- v
  27.         $mongoServer = "mongodb://";' X  F: h! @. G* f+ d# q
  28.         if ($config['username']) {$ s7 q7 Y& M8 T
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    # F! W# w( ~% f/ P: m
  30.         }  c% p. O. @8 C
  31.         $mongoServer .= $config['hostname'];
    1 \) }7 T3 V$ o) [0 y
  32.         if ($config['port']) {5 {; G+ k+ O! w7 \0 i1 n1 p0 l( O
  33.             $mongoServer .= ':' . $config['port'];0 L) O; [" q4 k; \) ~& ^
  34.         }
    2 Y3 w4 }) H4 E
  35.         $mongoServer .= '/' . $config['database'];# P2 i+ y8 U5 {1 j7 j( w9 y) h
  36. # k: o7 \9 _- v" k# q
  37.         $this->mongodb = new Manager($mongoServer);
    + Y2 [- H; m2 q& ~' R9 |" [
  38.         $this->database = $config['database'];
    9 Y1 d) C' V# {+ ], y' s
  39.         $this->collection = $config['collection'];
    : o9 b1 [4 N8 c
  40.         $this->bulk = new BulkWrite();
    7 ^4 j+ @+ p9 a7 T  o' p
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
    ( Y( m$ w; F' d1 Z  g) i7 H
  42.     }7 T7 d, f" C* o( r8 V
  43. - J+ `& b& \' Y' K. g
  44.     public function query($where = [], $option = []) {
    6 J+ u* Q' m4 {; f" V' ]$ K; }
  45.         $query = new Query($where, $option);
    9 r: f) Y- \+ i( x, G/ r
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);% |4 E4 F! M9 R1 y% V  ?0 e' R

  47. , z3 U( b( @4 i% Z7 d4 r- c4 x
  48.         return json_encode($result);
    ! S' P2 q$ c2 g' y! l
  49.     }
    - R" b# |9 a6 a  ]' r
  50. $ M: s. r! L" Z& l/ k+ r6 e
  51.     public function count($where = []) {' ]+ T  B6 z* J1 W2 L$ _, y
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);/ b0 s! d5 U% ^* }
  53.         $result = $this->mongodb->executeCommand($this->database, $command);- ?4 h' h& E' e# Y
  54.         $res = $result->toArray();' E+ Q% v& W$ X7 i4 ?2 P
  55.         $count = 0;4 [9 |3 ]9 \4 L% F+ `1 m$ u
  56.         if ($res) {
    ( i5 Y, ^6 [! c4 X/ K$ I3 t
  57.             $count = $res[0]->n;, v2 a' Y1 y) Q) _5 J( S& V( [
  58.         }
    " X3 j0 ?/ Y: T
  59. 7 Z6 m. U: N' H+ I% g2 Y1 g7 i
  60.         return $count;
    $ |  t, m( j# v4 P4 X1 J+ _" w3 j- b
  61.     }
    ; e+ b! |4 ^* ?) s, V3 u

  62. # E/ [% D: a$ U7 ~) x6 N4 a2 i5 ?
  63.     public function update($where = [], $update = [], $upsert = false) {
    7 k1 @4 Z) E( P
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
    3 }0 F: Z. q! Q6 T
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);# }4 U% |3 L# @2 v7 k. [' l. o
  66. $ S( n" Y4 z" i+ I
  67.         return $result->getModifiedCount();% b9 I$ {  Y- H5 Q, c: F7 B
  68.     }. m. ~8 l/ r8 H9 i% \+ S: y5 x
  69.   `: o- a7 s7 J- W- ^
  70.     public function insert($data = []) {/ H3 R$ }  p+ q3 n' z
  71.         $this->bulk->insert($data);6 r' G$ H. u0 W6 d% y! n
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    9 w, J; r1 v' C& u, }9 f

  73. 9 \! ^' [  G6 B
  74.         return $result->getInsertedCount();/ C8 i  L0 u& @# a3 B; C
  75.     }
    - M3 I! W* h' l! H9 ?
  76. 9 @, L! d& R1 R( m, J
  77.     public function delete($where = [], $limit = 1) {( G( g; X) a" z( @; f7 J2 {9 d
  78.         $this->bulk->delete($where, ['limit' => $limit]);
    ' h4 a# u- K* A6 X' j0 F# i( v
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);5 L$ ^8 Z8 O& ]) C& j$ i" }

  80. ( M0 r& X! L8 A
  81.         return $result->getDeletedCount();
    & _2 L$ V* ?; [6 f: T( s
  82.     }- z9 y' x  f7 x+ G" p* y) r+ F
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单
    6 T2 k3 H0 L, u: _9 t
  2. $lastId = $resultOne->getInsertedId();
    4 [/ I) z5 E( U: S" p3 P7 x
  3. $resultMany = $collention->insertMany($array, $options);//多. L* i  \9 h+ i/ |
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [; y( x2 s3 H/ \3 g2 i) @
  2.     '$set' => $values  R6 {8 {* D5 W  p! y' I: U
  3. ,[  w9 e2 c! R, d# I  _. M$ g+ H* {$ r
  4.     'multiple' => true//多条,单条false" S* O; a. U1 L% C# G9 m- E
  5. ]);
复制代码
  1. $collection->updateOne(
    $ U3 B$ w) {; W3 C; @' o
  2.     ['state' => 'ny'],$ Y+ s. ^' @( m- P' n& e- V) T
  3.     ['$set' => ['country' => 'us']]
    / C: ^3 P: g% `3 ]2 y8 R8 ]
  4. );3 m% n6 z& ^; ~" p
  5. $updateResult = $collection->updateMany(% x) D: n' e5 U/ p& a; d
  6.     ['state' => 'ny'],9 }* \' z( ~5 V; q; v# }4 E: i4 Y
  7.     ['$set' => ['country' => 'us']]
    # r; {! y3 i( t  ~. m7 ]$ ^7 F' d
  8. );$ x1 X4 S* Y1 }
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [2 \( o7 p4 D( L: n4 V& a2 N
  2.     'name' => true//指定字段* i: W! l- j9 a
  3. ]);
    9 |4 e$ S6 Q" w6 ~# A
  4. $cursor->skip(5);. O( X, {( ~! N5 }2 B2 R
  5. $cursor->limit(5);' g0 `" ]& V& v+ g; N
  6. $cursor->sort([) L; o" n4 _6 r3 g8 |8 @& r+ K
  7.     'time' => -1
    " V* H& m8 `# J2 j, W/ O( [
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [  O( y. z. r4 o, [* F. ^+ h
  2.     'skip' => 5,
    % y6 W1 v' V7 l! o2 u. l: v
  3.     'limit' => 5,( X3 v$ i3 f  W5 }$ [' }) B
  4.     'sort' => [) z' y- \! V7 l0 j
  5.         'time' => -1# y; S! r/ c3 \3 J
  6.     ],//排序/ n& K, m7 D( X; r
  7.     'projection' => [
    2 n1 x/ c, Z+ k7 V; `8 _, \. c
  8.         'name' => 1//指定字段) x) t& Q$ L8 w6 j7 m
  9.     ]
    7 P1 V) U  C6 t0 N- _2 L1 |. f
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [- u$ y5 R- E' ?
  2.     'justOne' => false//删单条% p4 G. }* T7 ^5 @6 f* [
  3. ]);: J1 A  P$ Q$ J0 l3 S
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);5 _8 |; @4 j, y$ H1 c$ ^  H( ]
  2. $collention->deleteMany($condition, $options);
    3 {" e  f! ~$ Y

  3. 9 X' R! q; L4 g) B
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    ( m" u% `  [% n. Q% P' B$ \3 d
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    / y+ T4 |3 E  }: L
  3. ], [
    4 c, z: `3 ~+ [; `" x8 x, O! N& w
  4.     '$inc' => ['id' => 1]//自增2 O6 t+ N3 k/ i
  5. ], [  `1 l# ^) A! s: P1 S6 q+ Q
  6.     '_id' => 0, L$ ]# Q) s9 ]" P, K% B
  7. ], [8 D0 ?- _3 q0 h# Y* a8 ~# S
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    4 h4 A( z0 @$ J
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([# R6 k4 w+ i# |$ E$ T
  2.     '_id' => $tableName, Y- _! `5 v5 A6 q
  3. ], [
    1 J5 ~; E/ A) t! m
  4.     '$inc' => ['id' => 1]
    6 F* [  j+ z& z; |$ A  H* L
  5. ], [
    ! j* y6 [" ^( W* S; k0 V
  6.     'projection' => ['id' => 1],
    9 R7 k7 T7 Z: [. R8 A6 d
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    0 n$ s7 j4 K; c2 w; @5 t5 T
  8. ]);
复制代码

/ Q6 V0 ~. U8 n& ^+ `$ h$ l6 Q* U) @2 f





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