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
    ) j7 e& I; I3 L8 k0 D3 K
  2. ! Z% ~) ?( q8 `$ I
  3. use MongoDB\Driver\Manager;/ K, ]; h* N+ o& q6 \& \
  4. use MongoDB\Driver\BulkWrite;. F3 X; w2 m5 k' E: N8 v
  5. use MongoDB\Driver\WriteConcern;
    & d6 F  R  e0 K7 L) J  Q+ @' G3 h
  6. use MongoDB\Driver\Query;/ m& C% s$ }! x+ I
  7. use MongoDB\Driver\Command;. y) d  x7 ~' h4 [5 Q

  8. 4 h% l- y+ F. ^/ g8 j0 w/ P# v
  9. class MongoDb {% b% v2 ^! Z6 G+ e1 P

  10. " \1 Y' J1 z8 y6 r/ q/ v
  11.     protected $mongodb;
    ( Y2 n. B! {' O. N, M
  12.     protected $database;& U5 j* [$ L& ^  o/ R; D; \
  13.     protected $collection;1 u3 R7 ]" ~" C5 Q1 ]
  14.     protected $bulk;
    7 l/ K3 A  P5 W
  15.     protected $writeConcern;
    * L. x% K- K) F, d. i" z' U
  16.     protected $defaultConfig
    " _5 [; K6 D1 k% _) E. F" h
  17.         = [
    $ N8 T8 r- D# w/ g" Y
  18.             'hostname' => 'localhost',6 `  G4 Z8 \% S/ P0 M. X( _% n
  19.             'port' => '27017',
    , g& I" `# K+ F: W0 Q# J
  20.             'username' => '',
    . x( W6 q! o1 k/ W6 N
  21.             'password' => '',7 ?1 f& P/ V' r8 D, j# ?$ z6 ]
  22.             'database' => 'test'+ r3 f3 g4 A1 L' {& b
  23.         ];
    , u0 k" ?( e; a0 D- E
  24. ! w$ K$ x9 F: l1 @
  25.     public function __construct($config) {1 C/ g& D2 q% h+ \4 n' m" m( [
  26.         $config = array_merge($this->defaultConfig, $config);  o" u; |6 z& I
  27.         $mongoServer = "mongodb://";
    8 @3 X) Q$ N; }4 _& K+ H
  28.         if ($config['username']) {
    ! E3 M- D* M. A1 l1 \0 T% I
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    7 D- y/ I4 w9 d% ~& G/ v
  30.         }& Q* U% C) h3 z# h
  31.         $mongoServer .= $config['hostname'];
    : M! O# _! @5 k8 `
  32.         if ($config['port']) {9 O1 I( E7 C' a0 T2 q
  33.             $mongoServer .= ':' . $config['port'];4 r6 X0 V! U9 K7 i8 H4 d
  34.         }5 G3 u( z+ W* n# Z8 H. R  q9 y
  35.         $mongoServer .= '/' . $config['database'];
    9 `1 ?) {) K. O9 ?' k: g
  36.   c! r6 x* _. O4 o% R& x
  37.         $this->mongodb = new Manager($mongoServer);3 X4 ]! H+ J9 `  s
  38.         $this->database = $config['database'];
    ! M  N7 Z9 c; q3 V
  39.         $this->collection = $config['collection'];
    . ]6 S" l6 s# i+ M
  40.         $this->bulk = new BulkWrite();
    ' z3 Y; U( O$ P6 a
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);& \1 s$ F. e( ]2 ?6 Q( w
  42.     }
    0 V5 r8 q' C1 T- i8 w! M; a
  43. / Z; a+ n  i  c! x. g" Z% D. O5 f
  44.     public function query($where = [], $option = []) {' t9 a$ w% ]8 F) o6 L
  45.         $query = new Query($where, $option);
    " R. Z' {$ E; B# ?# ^, p
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);; q, m  `" ^+ g& w; A

  47. ( T1 {; I; ]: A* ?
  48.         return json_encode($result);
    ; L8 q  _* r) o. P9 a7 d+ ^8 k
  49.     }  D7 t& H1 N& V- ]5 b! K

  50. 4 C6 b4 l$ S5 |  h3 d
  51.     public function count($where = []) {! a- L) l/ F3 C3 }$ S3 X
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);) {" V6 w6 c0 J, j, D. S
  53.         $result = $this->mongodb->executeCommand($this->database, $command);
      ^: l8 z; w- B2 O) v) G
  54.         $res = $result->toArray();! r! a! [9 \8 Q1 K0 c
  55.         $count = 0;
    . `! |% O8 c2 ?' H. O% n
  56.         if ($res) {
    ' o8 w- G  [  F) q; I' p1 V7 k
  57.             $count = $res[0]->n;* L% x6 r/ O9 \0 W
  58.         }
    ' U) r/ L5 ?' b

  59. 1 A- i' O- ?" z0 ]' H2 S' Z" ~1 r( q
  60.         return $count;
      H5 l; }* N+ B# D, [
  61.     }: x6 T: R+ {6 C; d  S

  62. ' Z& J. R+ {( V: a. o9 Y
  63.     public function update($where = [], $update = [], $upsert = false) {
    " }6 K) K7 F) m) Z: P  j6 V
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);0 W9 T" S4 c, M8 {  Z6 E
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);  I4 c' x" B- X
  66. ) l9 [9 H, ~1 E+ L
  67.         return $result->getModifiedCount();' P. E: W- J8 B+ k' w
  68.     }& {' `7 C  l' v+ h% {
  69. 9 q9 s' \& n( I
  70.     public function insert($data = []) {- _- v' u6 b# G1 @% p
  71.         $this->bulk->insert($data);
    0 Q3 X- H2 S2 r/ o# m: w( B& Q
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);: v9 X- Z* P; |& }+ t

  73. 9 t# W. j* ?# l) d. C4 o6 c% @4 l
  74.         return $result->getInsertedCount();
    - u* Q3 {! [9 B, n$ e; e  P9 o, A
  75.     }0 H- a& ^" B" g& X
  76. * Z" s/ _8 L8 I3 D% n) x" s( K
  77.     public function delete($where = [], $limit = 1) {
    ; ]- `& j; Q4 k+ b+ k
  78.         $this->bulk->delete($where, ['limit' => $limit]);; j9 l; F1 _( Z* Y1 O* W- I" I
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);$ \1 f8 F- q4 u7 c6 ?  ?. x
  80. 4 e/ ?* {8 c9 _1 H
  81.         return $result->getDeletedCount();
    - ]9 x' h+ N7 Z, L; A# u
  82.     }
    8 C7 [$ h# A% D! w5 i* H( x
  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 W9 m+ J) X6 s6 |+ X! J8 _) B- [
  2. $lastId = $resultOne->getInsertedId();- p" }& z5 _5 I; u
  3. $resultMany = $collention->insertMany($array, $options);//多
    3 k; D2 ]& H$ c/ R$ Z7 Z
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    ; v; j, U% X. y4 c; R
  2.     '$set' => $values$ W: e6 ?0 Y2 P; l4 M$ \9 F; \& x
  3. ,[
    8 h, U4 K# N: ]# h
  4.     'multiple' => true//多条,单条false
    3 Y" D- R6 E; ~5 {* b
  5. ]);
复制代码
  1. $collection->updateOne(
    0 i) i! o+ s4 Q) Z; _! Y
  2.     ['state' => 'ny'],
    & }- J2 m$ a( p; S+ s4 O% `& g
  3.     ['$set' => ['country' => 'us']]5 z$ n4 ~3 l) t) D& l& \9 Y5 A
  4. );* Q6 M% s# A: B& w
  5. $updateResult = $collection->updateMany(9 u/ x  X5 Z( k' U! q8 E
  6.     ['state' => 'ny']," h/ @8 V) @" P# [
  7.     ['$set' => ['country' => 'us']]* @7 e4 o/ K4 I
  8. );# K4 |0 t) N- ~: }" |
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    6 v' t* r- @0 B6 C' X+ u6 [
  2.     'name' => true//指定字段( G3 W0 L: d4 }! ]& {" g- ]
  3. ]);
    - g/ j. C+ |1 r& s7 L. Z
  4. $cursor->skip(5);
    + a, S% d1 \% l8 q' U2 M% s
  5. $cursor->limit(5);! A  F1 L# \  M5 V
  6. $cursor->sort([: b2 |$ B# Z- a- _4 w; k7 K* e- [3 d
  7.     'time' => -1
    1 C/ |- T2 _5 y# S! Z  Y
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    1 }  a) Z, l) m0 w5 N) I- \
  2.     'skip' => 5,
    % q* Y3 P! `; d6 A
  3.     'limit' => 5," [- @/ z& N7 S7 J& J) l% ?6 ~
  4.     'sort' => [
    2 C5 D% i. s$ n" \  |: E- E- B  I
  5.         'time' => -1
    4 @; R* E( u1 p% |4 \1 ~: @" h$ P$ @
  6.     ],//排序! T' n) _. I+ |- d- o: u. {
  7.     'projection' => [& l$ C* `# k' P# |9 F% d+ ^
  8.         'name' => 1//指定字段0 y6 ~1 h; G+ G9 S7 K! s6 f
  9.     ]( i3 o3 I6 @+ |& c+ S
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    / i& ]* o! f4 h. r! \( s; Y
  2.     'justOne' => false//删单条
    0 O" u4 S1 X. V. B  D
  3. ]);
    2 \. G9 J# |! _( _) h  ~1 A
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);; |- Q6 P8 X1 ^. ?  Q5 J2 i
  2. $collention->deleteMany($condition, $options);8 A, o% e  j4 [- V  K
  3. % S) `1 ^$ {9 Y* b" M
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    % ]$ y/ w3 j% [8 X- ~* V
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键! P1 r/ _. Z7 ~8 c7 j" W
  3. ], [
    . [; E  f; g) K7 D" x) e! _
  4.     '$inc' => ['id' => 1]//自增. q# U/ I- X' L5 U! n
  5. ], [
    ( K' x; ?3 q% ~& Z9 P! C
  6.     '_id' => 0
    5 t4 f5 f/ u( F! M( E! P0 y( y
  7. ], [  a7 U! P. }/ o! C7 s4 f: }1 L/ l" W
  8.     'new' => 1//返回修改后的结果,默认是修改前的) n7 k7 ?  F: I
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    1 \; h; O; W- l8 ~7 i
  2.     '_id' => $tableName% k: ~& }4 R8 x2 k( z
  3. ], [
    3 Q$ I5 B+ j3 |: j" M$ N
  4.     '$inc' => ['id' => 1]
    - s4 g: f- G; b+ n: c7 w% k/ r$ o% i7 ^
  5. ], [
    ) s& ~! M  a% J5 D
  6.     'projection' => ['id' => 1],: ^3 ~5 p8 q1 S+ T
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    1 _, X- p+ X8 M6 P
  8. ]);
复制代码

. G2 E. e# p4 _& o, \* G* u% N; {4 \! H# D





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