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
    + n7 c  F3 `) |' O0 b9 T9 P

  2. $ g3 u% ^' J5 p( b
  3. use MongoDB\Driver\Manager;4 H+ [3 g: u- L( v* E4 `; O3 E6 T
  4. use MongoDB\Driver\BulkWrite;
    " W; A. c4 a' Y* @
  5. use MongoDB\Driver\WriteConcern;
    8 z% ]# E4 k' i/ V$ Y
  6. use MongoDB\Driver\Query;
    " U; |) N& `& D8 \, L
  7. use MongoDB\Driver\Command;& u/ F: X$ U- ]* {1 S
  8. ' Q+ S1 k2 v! e' G
  9. class MongoDb {# K; C$ L8 p+ {  s0 K9 n" @: N9 {5 q

  10. 5 ?5 D) `% T! l
  11.     protected $mongodb;
    ! q6 ^* V3 |" z
  12.     protected $database;
    ) K2 d4 R$ ~. O5 u  O) W6 Z4 a
  13.     protected $collection;/ E( o% p3 a! u4 u
  14.     protected $bulk;
      R# z9 v# S5 l/ O; X
  15.     protected $writeConcern;
    1 I. `$ w: w8 T5 L2 S
  16.     protected $defaultConfig4 b7 {2 ^3 l  M$ q( x
  17.         = [
    & z- K* e1 H  z5 e
  18.             'hostname' => 'localhost',+ w7 v6 T& t: E* U7 Q+ y( _  b5 b
  19.             'port' => '27017',
    2 r/ V7 w- k% Q- b6 X0 |  H" D7 }
  20.             'username' => '',' S) ]% b7 H+ u2 B8 W8 Z  [1 b- \9 ]
  21.             'password' => ''," M. N9 f9 s( b8 D- \5 A
  22.             'database' => 'test'
    & W$ T: r0 t- H! A2 o" F5 t, E1 v% @
  23.         ];
    ( W2 }' y3 k2 A

  24. 0 H7 Z) H4 K2 ^( [+ E
  25.     public function __construct($config) {* C% x& t! R8 B% Y2 _9 }
  26.         $config = array_merge($this->defaultConfig, $config);
    & B" B2 F( m1 d5 ^
  27.         $mongoServer = "mongodb://";9 k( M( C2 h1 `$ [9 Y" Z& Z
  28.         if ($config['username']) {  u% B* e8 M, G0 S5 r1 c
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    ) _3 G2 }; v  v* m& e4 Z
  30.         }# L0 x& Y  `5 r7 o
  31.         $mongoServer .= $config['hostname'];. s) H. e) t. K) D
  32.         if ($config['port']) {
    * j' |$ h9 |* T" K5 l2 J% i
  33.             $mongoServer .= ':' . $config['port'];$ |! n+ Z* {  R1 r: v$ R
  34.         }
    ( w3 h2 f: ~9 \9 b+ t
  35.         $mongoServer .= '/' . $config['database'];1 G: d! Y5 V/ y
  36. ) @2 _: o0 R& q" C$ u0 C* J0 h
  37.         $this->mongodb = new Manager($mongoServer);
    2 p+ ~$ n, B3 r7 J
  38.         $this->database = $config['database'];+ {3 t5 A9 M0 v: C. Y0 g
  39.         $this->collection = $config['collection'];6 D# }4 J2 v' ^$ j) H
  40.         $this->bulk = new BulkWrite();5 ?: R4 a( G. Q6 L1 |
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
    % z  V- p3 S. D1 U# p: {" R
  42.     }
    . K& L5 k8 Q& i1 p8 c" p3 }
  43. ! Q; k( W5 m6 a+ O; B" `
  44.     public function query($where = [], $option = []) {
    # M6 O& J4 ^( S' g' g
  45.         $query = new Query($where, $option);
      J' V* n- [6 U% S
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
    ( n% J' G* n, r# H+ L* L# s( ?8 o
  47. & z) N4 w# I5 A' s4 r
  48.         return json_encode($result);' L$ w$ {# Q6 `% Y2 _4 B  J. ~! X+ V( L
  49.     }
    4 q$ J. q1 B& m6 x( g, L

  50. 8 f6 [0 Q! @! ?1 v! ]! s+ h( `
  51.     public function count($where = []) {% u9 ^- ?) W" @. r* H9 m
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);7 B) O. J% l( X- L3 r4 [
  53.         $result = $this->mongodb->executeCommand($this->database, $command);1 n1 N; B7 i+ c$ p
  54.         $res = $result->toArray();
    , B% ~$ z  L7 ?0 k: h2 J
  55.         $count = 0;
    8 l% J* D5 G+ \
  56.         if ($res) {' F9 I& m& v  K1 I7 `
  57.             $count = $res[0]->n;
    . b/ h  o8 z  U; K: N1 l
  58.         }
    % P! n# p1 B! S7 u. V( \4 x
  59. + g# p" B9 z# _4 `# s1 `
  60.         return $count;
    - n$ x0 q+ @; y# _7 I3 S4 b( v
  61.     }) E* q  @9 Q8 l$ F8 b5 c
  62. " p& {5 f9 j, Y( m9 D" [' A
  63.     public function update($where = [], $update = [], $upsert = false) {
    6 Z" W) `$ @/ Q9 d
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);" |1 @- X  m6 w* M. T1 E% L  a
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    * t) t- [8 R0 p. d; s) D

  66. 5 w* m' h5 E( w1 s5 ^! U8 d
  67.         return $result->getModifiedCount();
    2 \2 u5 t# L9 `1 W; E* H1 l# x7 T
  68.     }
    ! w3 |) n! \' M3 n4 I( K# H
  69. " y* M, w( E! a. M  b7 R
  70.     public function insert($data = []) {
    $ ^3 E2 e2 l( J; s# m
  71.         $this->bulk->insert($data);
    * @/ [( i  {* }; {" X2 C7 h# W$ N
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    8 u/ H7 S- R2 t! A- A, w) U

  73. 6 Q7 V) y* s- h8 `5 L' o
  74.         return $result->getInsertedCount();7 @8 R& m8 \9 m" F* w8 ]5 Y
  75.     }  l7 ]' L$ Q+ z# h* {' Y2 D

  76. & Y. N3 V+ s# X2 r2 d
  77.     public function delete($where = [], $limit = 1) {
    8 P- ?( ]3 W) n: L
  78.         $this->bulk->delete($where, ['limit' => $limit]);  G  a/ w& z$ q) ]% U6 v
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    4 k) k7 U4 i3 B6 a

  80. / s$ w1 y0 S; O- h$ B
  81.         return $result->getDeletedCount();0 g, M  e% P" [3 k6 Z! A
  82.     }
    , Y! B  @3 \( ]- K7 M1 H3 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);//单2 M1 A1 \0 d$ j& q. ~$ G  ?7 d
  2. $lastId = $resultOne->getInsertedId();
    0 q: e( y' X; i* ^( j: {
  3. $resultMany = $collention->insertMany($array, $options);//多
    ! B# s. r" d/ M. b& u9 |  m
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    : T' r- E  }- o9 u; a
  2.     '$set' => $values$ d$ |3 ~" W5 G
  3. ,[
    8 N5 _$ Y5 O/ n4 |* ^! f/ U
  4.     'multiple' => true//多条,单条false$ N" e: D$ R. x) s/ P0 ~. t
  5. ]);
复制代码
  1. $collection->updateOne(9 l8 G0 U8 c3 T' \" h# H
  2.     ['state' => 'ny'],
    / m6 @- ?5 `9 ]) t2 C. e
  3.     ['$set' => ['country' => 'us']]
    7 r# e* N) k( K
  4. );2 R/ j6 L4 O& c' a+ T1 L5 M
  5. $updateResult = $collection->updateMany(
    ! O4 `1 F( h, _0 r
  6.     ['state' => 'ny'],
    - r  ]5 k8 _+ {* _
  7.     ['$set' => ['country' => 'us']]" R' f8 _# A: U- |' B7 F
  8. );
    3 D/ c: U" e. E' g
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [# i4 y' s/ q: r' |  T) c
  2.     'name' => true//指定字段1 }6 _! \" n$ l; _( e4 q" e
  3. ]);0 V' Z! Y+ z4 B4 d/ d2 z7 X
  4. $cursor->skip(5);
    ! P4 f! O; a7 a1 F$ I4 j& [5 [& b
  5. $cursor->limit(5);
    + b) \% m% Q0 w6 O+ p
  6. $cursor->sort([
    % O7 y* e6 k  o; a" U/ G8 P
  7.     'time' => -1
    % S. o, _' }6 n0 N  ^
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    2 r" |$ B4 V4 ?: S1 {: T! b
  2.     'skip' => 5,
    * m, e/ q- q0 n* `# Q7 j% F
  3.     'limit' => 5,
    1 o! O# O7 @/ y0 e
  4.     'sort' => [
    0 F8 t( {* @" w/ B
  5.         'time' => -1* }3 |+ }8 g& |- M! g
  6.     ],//排序
    ! F9 }9 i& u& N5 a9 z. R/ W/ U
  7.     'projection' => [3 T8 z! l7 _0 G, D1 y9 Z# ]% r9 d
  8.         'name' => 1//指定字段# s3 j: Z& r/ P( I" i
  9.     ]- _9 U+ z2 H5 e! N+ F' ^
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    * J  M5 W# I# I4 s- A. X
  2.     'justOne' => false//删单条4 u- _8 W3 ^4 @7 Q
  3. ]);8 [3 P* \9 T5 m3 r0 x/ |' i6 L
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);/ f; [5 L/ X3 Q9 N; H5 p. V
  2. $collention->deleteMany($condition, $options);- u6 P: N% r4 V' A/ V0 w

  3. ( q" q2 }4 L0 z7 M) u
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([7 S+ C5 M' [, u
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    1 y$ {5 `' U- g& B. A
  3. ], [
    ( z5 m, {, C* w& w% y
  4.     '$inc' => ['id' => 1]//自增+ V$ u! M# o: m) C2 G# s
  5. ], [& N" z0 |$ {6 o  l6 h5 F
  6.     '_id' => 06 `0 u; G. B3 L0 k
  7. ], [8 Z  y1 u. G4 r5 j
  8.     'new' => 1//返回修改后的结果,默认是修改前的! J4 _1 a% P/ H9 h
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([# \4 M7 a. |" x
  2.     '_id' => $tableName; u+ ?$ h& ~0 Z" Z3 R* X7 E
  3. ], [3 t! ?% G: [; p9 z" \5 _, K9 d
  4.     '$inc' => ['id' => 1]+ x5 Z6 ?+ j. u' H( t1 }) {
  5. ], [; V, Z* ?9 @6 Z# ~6 Y/ w
  6.     'projection' => ['id' => 1],
    ) o/ Z! W( B# T+ ?; O- f% r" {. r
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    8 [8 [) n* G) r+ g; \' |. h
  8. ]);
复制代码

. f9 e* S( ~% M' p  O2 d+ o
8 E/ F: |( k  r7 b6 M% g




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