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
      y/ v' y- F" ~2 z; t

  2. ! F2 T% X9 E" Z0 {$ p/ I
  3. use MongoDB\Driver\Manager;& i- G5 m  [6 W8 j; ]9 C6 U
  4. use MongoDB\Driver\BulkWrite;- o% Q, A5 [* w& Q
  5. use MongoDB\Driver\WriteConcern;" h& W$ L& J/ p! {+ d9 F3 v
  6. use MongoDB\Driver\Query;
    $ v- i/ C- \8 E
  7. use MongoDB\Driver\Command;
    3 `" P1 F7 h7 G( [
  8. 3 J) P3 Z8 d* h5 D
  9. class MongoDb {1 e2 C  X: c9 f9 @
  10. : ?, H- j7 O, T& [* J  T( q' {
  11.     protected $mongodb;
    & U. z/ c- G7 \, |; {1 q8 F
  12.     protected $database;; r$ e% u: d! r  w* x
  13.     protected $collection;+ K' B& ^7 E* v% x( J7 w8 o
  14.     protected $bulk;: ~2 @3 G5 x' v8 L
  15.     protected $writeConcern;% O! a9 C* a2 p+ |& l5 n
  16.     protected $defaultConfig. C+ j( F# g6 |" g
  17.         = [
    & c! L; \% d& j6 P; e( q7 `* u
  18.             'hostname' => 'localhost',2 i, v. ^# V5 h% J: y/ V% V8 d( j
  19.             'port' => '27017',
    ' G: _, Q+ t# J7 r! d7 U
  20.             'username' => '',
    7 o7 L$ O) P/ x7 C! |, T
  21.             'password' => '',
    / K2 V* Z, x8 o% Y
  22.             'database' => 'test'2 {8 f' e: ]' z) }+ Z4 E
  23.         ];: y  J2 p% |  i* y
  24. 5 g! ~/ Y: ~6 H: Z! \2 W7 B) l
  25.     public function __construct($config) {
    3 c' v: @5 x! C
  26.         $config = array_merge($this->defaultConfig, $config);8 a! x* R* z5 k8 M
  27.         $mongoServer = "mongodb://";2 U7 y9 y5 X% ?( q' j
  28.         if ($config['username']) {
    : R4 M' O' H1 e* o$ Z$ A' X, B
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    7 b4 Q; ~& s0 C, e6 J2 i. d& y. B
  30.         }
    , Q. Z( R; i7 D4 \, P  Z
  31.         $mongoServer .= $config['hostname'];' e+ {' [, R6 `% ]7 o+ W
  32.         if ($config['port']) {0 k0 s% m! K5 y" h; O( ^
  33.             $mongoServer .= ':' . $config['port'];
    + g7 V# T9 z, P$ y6 G: V
  34.         }! j* h4 q0 \1 n: m2 B2 V2 _
  35.         $mongoServer .= '/' . $config['database'];
    ' K2 f5 A7 N  a8 h5 A

  36. - k) a, e6 l* i/ _8 A
  37.         $this->mongodb = new Manager($mongoServer);
    3 a+ N) M3 p+ q$ ~- s6 k
  38.         $this->database = $config['database'];/ n' k. n9 H7 n" b
  39.         $this->collection = $config['collection'];& D$ [1 ^( E' L; Q+ O/ E& T
  40.         $this->bulk = new BulkWrite();
    & O; E3 A: F0 D
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);! S' _/ Q% r- t3 u, a# t! d
  42.     }
    / _! z' R0 {5 w8 r! b
  43. 8 p$ s" e+ J! E" n5 R
  44.     public function query($where = [], $option = []) {  I; B) W: w% k1 ?
  45.         $query = new Query($where, $option);) y7 @  c$ u! l1 `
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);- C1 I7 N; W/ c: F0 P
  47. 2 O+ F5 l& p8 l. D8 \7 E* G- X
  48.         return json_encode($result);4 ~: Z+ x8 _) R, L% K5 E
  49.     }
    / W$ g3 a; h' `# t
  50. 7 H9 X/ a! W( J  T
  51.     public function count($where = []) {
    ! \, g& d" K% G. \
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);
    8 o8 U. y$ }) y" g/ W! y) L
  53.         $result = $this->mongodb->executeCommand($this->database, $command);. W) o! T* n$ V7 g" ~
  54.         $res = $result->toArray();
    + }& a7 ~6 [( K: j8 o" x) e5 |- S
  55.         $count = 0;. g" n8 C) a% I- u" g
  56.         if ($res) {
    & h; n+ H! d3 t6 Y
  57.             $count = $res[0]->n;
    5 r- ?2 y% ?) S0 ^8 I
  58.         }
    - K* L3 n2 j* O

  59. . _$ Q  b# B( g. }. b0 K/ n
  60.         return $count;
    * Q$ f* ]  W9 b' H/ q
  61.     }
    2 E7 r- [9 n6 G3 p% u. \

  62. $ W2 R+ p  J( Z( I
  63.     public function update($where = [], $update = [], $upsert = false) {& |: E: l3 X/ u- h  Q! R8 b; y
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
    % W0 e/ p* S; K: }6 S; [
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    # c, t; ^& }+ L. }
  66. ' ^# e. T8 }" U9 _
  67.         return $result->getModifiedCount();" }; F" G; {' `# K8 E7 |
  68.     }
    " w) j3 w' H. @( m2 M8 k# _% k
  69. 6 {4 \7 t% W- g1 ?
  70.     public function insert($data = []) {2 P5 y- D+ ~1 _0 Y* f0 Z: U
  71.         $this->bulk->insert($data);+ C2 F9 }  j) I" N! u, X) v- G
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    6 M8 _: H$ U9 I! M$ l6 S
  73. 3 m3 I  @; G2 \# t; e1 [- v2 p
  74.         return $result->getInsertedCount();
    8 d) x/ ^. `7 D, {. C
  75.     }! f6 {# |; ^) @- @9 _5 g6 D0 b

  76. 2 ~$ ^% H9 v" H7 P
  77.     public function delete($where = [], $limit = 1) {0 z; G$ D# a& Y; h8 u/ y0 d% |
  78.         $this->bulk->delete($where, ['limit' => $limit]);( }+ c  r9 ]. `3 d
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);; n1 w9 e5 m' Y" X, T

  80. 0 _( j- x+ u1 `" Q
  81.         return $result->getDeletedCount();
    0 _$ O1 R5 U2 U
  82.     }
    * m0 V/ c7 K! s2 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 W0 o# T! A2 j, F- Z
  2. $lastId = $resultOne->getInsertedId();' c' ]4 e. _/ [* K; ]8 i/ y
  3. $resultMany = $collention->insertMany($array, $options);//多# k6 H' K* o! p1 v
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [) B( {. C+ t5 S% H
  2.     '$set' => $values
    7 B0 H& u" O( h4 b+ X
  3. ,[
    7 H6 r( _$ J/ e* d
  4.     'multiple' => true//多条,单条false
    4 N( X2 I1 }/ I0 W
  5. ]);
复制代码
  1. $collection->updateOne(
      k- K  _" ~# `/ z
  2.     ['state' => 'ny'],9 O" A( O: D+ s  r7 ^
  3.     ['$set' => ['country' => 'us']]
    ! C: O+ c3 G' G( ~  j8 T5 I- i
  4. );2 I$ i* v5 ?0 b
  5. $updateResult = $collection->updateMany(
    5 a5 e- I0 \8 O8 k+ Z1 B3 J( T; X5 Y4 b
  6.     ['state' => 'ny'],5 S, u7 D3 y* m, P1 [+ l  S% C" X) F8 p
  7.     ['$set' => ['country' => 'us']]
    . P! o1 }. H  p% Q
  8. );
    ( ?8 G. e$ O7 C1 V$ O
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [5 d; K1 s4 p- q; J
  2.     'name' => true//指定字段7 Q3 O6 q1 O% k
  3. ]);
    ! K/ c5 J/ w+ i0 [6 t+ L+ T
  4. $cursor->skip(5);' {! }; B2 |7 f. t9 _: c" `% N
  5. $cursor->limit(5);* x1 u& ?% A0 Z' z
  6. $cursor->sort([
    1 A( R6 a! d' d5 H
  7.     'time' => -16 ]0 o: @+ q1 W# ?
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [- @  v! B. |0 q  r
  2.     'skip' => 5,
    ' ^+ u/ ?/ J% B# m
  3.     'limit' => 5,4 D# |1 F  @2 I& q
  4.     'sort' => [
    % J, J; ]4 b, x$ D" |+ b
  5.         'time' => -17 p0 i# y# e0 ^7 Q  i1 ?
  6.     ],//排序
    2 k1 H" ]" u# X2 e8 F/ t
  7.     'projection' => [* d+ {9 M# x' j  R  J9 a
  8.         'name' => 1//指定字段! u- c4 n1 y$ ]7 z1 B* c4 {& y
  9.     ]
    ! @; \/ e- o( n4 y5 n
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    / N7 r: m7 _/ C4 Q7 j
  2.     'justOne' => false//删单条* f+ w) b: s7 d) P1 s
  3. ]);, i( P; b3 J9 ^0 V. `
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);
    % F% y8 X1 E! ?  T
  2. $collention->deleteMany($condition, $options);
    + s4 i2 q' x8 N- D6 U, k
  3. : [% x1 H8 H4 ~
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    % n3 I8 ~, q! A: x4 |1 n
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键3 l' e5 p  c# z( {3 \5 X1 M
  3. ], [, p1 K$ {. x- o# ^/ g9 u
  4.     '$inc' => ['id' => 1]//自增  }! }" X1 V  I  V
  5. ], [( @" S2 Y9 F$ C$ }# g4 l" v
  6.     '_id' => 0+ F3 X1 C7 I& J$ \8 l4 ], ]5 D
  7. ], [; ?( l- A! @) F! T2 F9 t8 b
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    9 w4 Y+ ?* I& g6 V) s7 C
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    0 w  x. y4 @8 B, w. u
  2.     '_id' => $tableName' j8 j* U1 k3 w; T
  3. ], [
    8 J0 }  W% W$ a5 z
  4.     '$inc' => ['id' => 1]3 ]7 ?+ e" [& L- M3 R2 U4 T
  5. ], [+ m: K% E+ N) s7 \
  6.     'projection' => ['id' => 1],
    3 I. t: [5 C6 i
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER, I  |! Z; S& K! Y0 c  ^: _  a
  8. ]);
复制代码

8 T+ o7 a2 w+ L6 A- ]6 j- _& }' n$ n; R) i" w" }. v! G$ r





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