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
    * ~0 f$ W: K+ V
  2. 9 f6 I! Q, G/ L& f' `
  3. use MongoDB\Driver\Manager;
    ( {7 ^1 D9 y0 @: |* V1 ~
  4. use MongoDB\Driver\BulkWrite;/ o2 b) q, T5 A0 S5 r, k8 w, x
  5. use MongoDB\Driver\WriteConcern;
    0 A& B9 q; Q! N/ e, ^$ k7 b
  6. use MongoDB\Driver\Query;
    5 {8 H+ U! j9 f' u3 ?
  7. use MongoDB\Driver\Command;8 m# Z3 @  J" G+ E

  8. ' x; Z/ Q5 _2 k7 F
  9. class MongoDb {' y: R5 Z; k3 E$ _/ a
  10. . H1 a# z/ @. G
  11.     protected $mongodb;
    / a2 S" R% ^) c! ?$ J! O' |
  12.     protected $database;
    ) v! k6 |) q/ D
  13.     protected $collection;
    . m8 M6 W' i" R7 e' ~
  14.     protected $bulk;& K7 R3 a; E3 D' T; m" h6 @2 a
  15.     protected $writeConcern;. O1 m% A1 ~# t! B: \. T/ K+ B
  16.     protected $defaultConfig4 `; ]0 X6 O, Z( `1 Z  `
  17.         = [
    / P/ Q  @! p7 ]; n. I9 k, |# K
  18.             'hostname' => 'localhost',
      g" C* n" T, m) j- O' k
  19.             'port' => '27017',
    8 i& X- N! Z1 J. I) ^1 X
  20.             'username' => '',1 [; H* G2 e6 u5 h
  21.             'password' => '',
    ! e" n7 `" v: Y  T& ?7 I
  22.             'database' => 'test'
    ( u; Z6 _8 @) N/ k* i- \' r# ]
  23.         ];
    : H2 D$ K" u1 e+ D. ]- s
  24. $ G, @( ?' ^" \4 ]+ ^9 o; a! T5 P
  25.     public function __construct($config) {
    & Y, W! K  F- ]$ l
  26.         $config = array_merge($this->defaultConfig, $config);% q: A' \$ ^9 _" n7 n$ t" H& ~
  27.         $mongoServer = "mongodb://";6 Q" c. X/ i' F2 t- h
  28.         if ($config['username']) {
    + t" v) v. ~( ?/ M
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';' `$ R& F7 q( O6 {6 t, Y' K: e; E
  30.         }
    1 u3 O1 C+ H8 ^
  31.         $mongoServer .= $config['hostname'];- v4 ?9 l" g( c# V  r4 M/ ^3 O
  32.         if ($config['port']) {
    & o  r! l1 |8 Z; A
  33.             $mongoServer .= ':' . $config['port'];
    - p2 }# F7 G! f% I3 g. f1 Q' C$ h
  34.         }
    ! ^  u$ C* [/ G* x8 w+ t) L
  35.         $mongoServer .= '/' . $config['database'];7 j' ^+ \% }1 {5 F

  36. # E2 V- N* ~, w/ u: g- P
  37.         $this->mongodb = new Manager($mongoServer);2 `4 a7 R# z1 |' o4 k
  38.         $this->database = $config['database'];
    2 H3 j- F* _) _+ K0 K  K, Y
  39.         $this->collection = $config['collection'];
    9 l. j7 G+ m) y1 h5 j; ~
  40.         $this->bulk = new BulkWrite();
    $ r0 o, z, f. s' i. P& _1 D
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);0 j! x3 @/ g' D" \, J3 x3 Q) l
  42.     }6 ?3 q, X, s0 _7 E3 b+ J  p

  43. 9 ^5 l6 u- ^+ s- l9 f* H, Q: S& h
  44.     public function query($where = [], $option = []) {
    " O! b8 E: q  g+ h4 I. l9 [; c, P
  45.         $query = new Query($where, $option);) e, O; ~$ U: U& }
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);+ W; H5 ~: m, w( {2 W7 z2 C
  47. 4 C: J! _- y9 y/ B; T$ {
  48.         return json_encode($result);
    ) g* V  T2 F, u& j- i9 ?
  49.     }  e4 I) T- q4 U$ k9 f1 L
  50. + J' X1 P5 n$ ~# J* Q, ~
  51.     public function count($where = []) {
    2 N& t5 w# h6 i5 |* s8 Q
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);# {& U& ?8 R$ S. n8 h$ O
  53.         $result = $this->mongodb->executeCommand($this->database, $command);
    # M9 E6 [% L8 w$ k% C- q
  54.         $res = $result->toArray();* R  C7 Q  a# i* A- c  Y0 X% d- D  G
  55.         $count = 0;
    ) x1 P0 e1 J( W2 ?& {: k
  56.         if ($res) {
    , q# W) _. n" R( w  z: d7 U
  57.             $count = $res[0]->n;- D4 \; I( ?( V0 [& x
  58.         }2 N# @; n6 M9 t( a
  59. 1 s  Y& E0 L* G. d4 A! ~
  60.         return $count;+ A2 {! n) b; L0 x" x$ h
  61.     }. u3 i/ X7 {7 n, J* V
  62. 4 L9 c6 I: O- Q8 q
  63.     public function update($where = [], $update = [], $upsert = false) {( ]* p  N' Q9 u5 M! i
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 C+ J; _' j" i
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    - |, D( {- ]( K' H3 H: ~1 }

  66. 8 F9 S$ G. A9 o5 X8 @$ n: M  p
  67.         return $result->getModifiedCount();
    & l  _1 J+ @# O4 F
  68.     }
    . y& D  h: b' i
  69. + _0 u9 [0 K  n( J: s
  70.     public function insert($data = []) {
    0 V9 G8 K5 \' a: x7 a
  71.         $this->bulk->insert($data);
    9 B: @9 [# c0 }! W
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);2 G3 P! ]" w  h+ {" y$ r

  73. + Y9 z" E# h8 L# q& O: b3 r7 |9 {: e
  74.         return $result->getInsertedCount();
      n# P. m! {; y
  75.     }
    3 ~) G- K- e" F5 i$ i$ x6 q
  76. $ R( Y' U# [, ^" @
  77.     public function delete($where = [], $limit = 1) {
    ) x5 M  y; [4 n, ^4 K5 o1 V
  78.         $this->bulk->delete($where, ['limit' => $limit]);6 C2 _' H6 c, |" x5 ^! {( T
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    / H8 h; G6 g2 j/ B
  80. , b# ^( `) j$ ^, G
  81.         return $result->getDeletedCount();3 v+ V4 J! `# {5 D1 S
  82.     }
    : X- c1 a( @& |$ a& a
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单: N* H+ Y- M' b4 u
  2. $lastId = $resultOne->getInsertedId();
    3 `' V4 b& e- ~; A! r
  3. $resultMany = $collention->insertMany($array, $options);//多, E! E5 v) ~7 X' F# z& ~' g- k
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    ( y  u1 L. R- b5 w$ r  w; o2 u( x
  2.     '$set' => $values9 H  m4 L; R& l) F4 g
  3. ,[
    3 ~: N. y+ k4 z$ ~
  4.     'multiple' => true//多条,单条false+ c/ f# k- c! q+ ~! O( r+ [
  5. ]);
复制代码
  1. $collection->updateOne(
    , T) O. h6 b& \1 R3 @6 L5 W
  2.     ['state' => 'ny'],9 S, |- {$ Y7 @% D. m6 T
  3.     ['$set' => ['country' => 'us']]; }& k5 V4 m- b1 I, f$ @
  4. );
    * O/ c/ d0 O8 }4 r
  5. $updateResult = $collection->updateMany(+ z: v! ~  w* y/ w
  6.     ['state' => 'ny'],
    ( K7 \6 f/ R7 Q5 l8 s, {
  7.     ['$set' => ['country' => 'us']]. g3 i, ]1 n; V5 ]+ F1 n
  8. );
    & p6 ]$ A7 j+ z8 @
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [- L6 V* O3 T  Z1 ^4 h
  2.     'name' => true//指定字段0 f, f( A. I) w0 g) w3 a
  3. ]);
    9 Z8 u$ k8 O8 t
  4. $cursor->skip(5);" O- E6 j( \: }$ B# n% o2 l
  5. $cursor->limit(5);7 @! W( R/ m, x8 m
  6. $cursor->sort([3 Q% e" a# o; _; a: N" l
  7.     'time' => -14 ?" C' W9 D. N- s4 ^5 M: [
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    + f/ l  X  [* o1 l. r
  2.     'skip' => 5,4 o$ w3 q: V/ p; B8 {$ ]( z6 [
  3.     'limit' => 5,
    ) X; Y  e" H  [7 d% m% n
  4.     'sort' => [+ a- u  o5 C( p6 d% n/ V
  5.         'time' => -1
    & ?6 {5 a( l+ E0 a" A
  6.     ],//排序
    0 g" r( t# i/ q1 @3 l/ K5 G2 _. p& Q
  7.     'projection' => [2 j+ q1 k9 }* Y/ s0 \# f
  8.         'name' => 1//指定字段
    5 h+ p6 G4 W0 f! ]# I
  9.     ]$ x+ i0 R7 N, b5 T
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [2 \; p) r: s$ B$ Z. i/ G% @
  2.     'justOne' => false//删单条
    1 i6 L5 a4 L. U/ W! k3 Z/ Z
  3. ]);
    ; {- x8 }' T0 e8 p) _! @9 p' s# K
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);2 O9 n1 X, P9 t' C
  2. $collention->deleteMany($condition, $options);
    : K- M: `% p& G# m" z+ h

  3. 0 P3 A  t: I, Z/ h4 k
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([3 @7 _# x, B% m. E7 V( m1 S
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键# b: v0 \: e! L8 q( g
  3. ], [" G# `) f3 n" x: b0 f6 ~
  4.     '$inc' => ['id' => 1]//自增1 F/ }6 h) u! M* \
  5. ], [
    3 V2 i: j. A7 ~+ a/ p/ G
  6.     '_id' => 0$ ~3 g# N5 _3 V( y" ?7 D5 B8 {: f
  7. ], [
    ) M" d7 m4 Y8 o( p8 a6 E% O  k
  8.     'new' => 1//返回修改后的结果,默认是修改前的! X+ |3 a+ |) i9 p$ [  e- O
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([9 C% @# e) M- Z; z+ t
  2.     '_id' => $tableName- a. ^! _$ @$ a: J
  3. ], [
    ( z& A$ @# X' f3 n6 b8 y
  4.     '$inc' => ['id' => 1]
    6 u( p7 S  ?! N. a9 X" _" _
  5. ], [4 X* Z/ [" l6 F6 k. O# z) l
  6.     'projection' => ['id' => 1],. H8 c+ Q/ h8 {5 k9 l1 b
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER% s# X# `! p: D5 P( s, p5 S
  8. ]);
复制代码
6 K+ i+ s8 V5 O* D+ ?

3 J8 G5 v# _2 B




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