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
    ; s2 G) i, ^( j0 q4 C
  2. 7 a* r- Y$ \, I8 Y2 b
  3. use MongoDB\Driver\Manager;
    " e9 c: }8 n: L9 z
  4. use MongoDB\Driver\BulkWrite;
    6 w/ c; U0 s% z0 q0 K3 M: p% S6 f
  5. use MongoDB\Driver\WriteConcern;& S$ d9 Y) E6 I/ d1 q4 F+ k8 _
  6. use MongoDB\Driver\Query;# S$ D7 s0 K% g( x) U' d
  7. use MongoDB\Driver\Command;1 y" O! n: v. I$ r; t. ?

  8. 1 N' I" s/ `" w) k6 ?( z7 B& Q0 {
  9. class MongoDb {& Y$ b% D: a8 }7 W! a* u" K# G$ l6 |
  10. ; N1 t8 p9 w' h4 v* s
  11.     protected $mongodb;
    9 G1 l7 m  M' s: z7 T. t7 q9 j
  12.     protected $database;- `$ F( s- v. ]" S5 J
  13.     protected $collection;
    * s' `( z1 _1 @- Q: m. Z. V
  14.     protected $bulk;
    % o' @0 Q! K; {! ^2 W
  15.     protected $writeConcern;
    1 i; T4 a. C/ a3 \, M, L
  16.     protected $defaultConfig1 V: ~( s: a5 h* W+ @
  17.         = [- f5 w4 U+ E  h& I# z% R
  18.             'hostname' => 'localhost',$ c% F0 ?! T) ^3 K" f
  19.             'port' => '27017',
    ) h! @2 d' ?# K% W4 S
  20.             'username' => '',
    7 {( H, G" c) u3 ?# h2 X, H
  21.             'password' => '',/ w) P+ W+ ], C( B
  22.             'database' => 'test'
    ; T4 W1 U/ T, o) E  X6 p
  23.         ];
    " S. d3 S" j; z; e5 k) I9 h1 ]% X
  24. 6 N4 Z& X! r" @+ I
  25.     public function __construct($config) {9 M# x9 ~  Q: v- k6 S
  26.         $config = array_merge($this->defaultConfig, $config);
    0 C0 i/ |# b8 s3 I* O- ?8 n4 ?
  27.         $mongoServer = "mongodb://";
    , R, C- F7 r( O7 X4 {5 X
  28.         if ($config['username']) {! f3 r8 f* I: ^9 P  j
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    . O) ^* |+ x1 U! d; N
  30.         }
    4 r5 v: u. x+ Z8 z0 q! O6 s
  31.         $mongoServer .= $config['hostname'];
    / e' v8 G6 ^2 E/ C8 _5 T
  32.         if ($config['port']) {( ^! |- h( t5 ~/ J) g" y
  33.             $mongoServer .= ':' . $config['port'];) }( ]: V' `( g- d& K8 V
  34.         }1 n# W, a. c& p; x' j
  35.         $mongoServer .= '/' . $config['database'];" H! Z+ y* Z# r% O2 g

  36. . s! K/ }3 d3 z3 R& z3 O
  37.         $this->mongodb = new Manager($mongoServer);
    4 W" f3 p1 J4 T8 g; Y0 h+ F5 o
  38.         $this->database = $config['database'];1 H" b0 O# ]8 m5 a4 A+ a
  39.         $this->collection = $config['collection'];) n. W: h; J: `! f
  40.         $this->bulk = new BulkWrite();
    1 m  k; Y, @" U4 P
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);5 {  y7 }2 _  f% L) u
  42.     }  n% g4 ]- k6 b

  43. : f, @5 s: m7 _7 s" h- d2 K
  44.     public function query($where = [], $option = []) {3 q" U0 P6 w; q4 O
  45.         $query = new Query($where, $option);* b6 b! q7 @- v: H' h
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);* ~2 a& l" M. Y# ^1 R8 ~

  47. / m- C# F2 E9 q7 L% y# }4 C
  48.         return json_encode($result);6 t- ^5 \4 t& h$ w. ?  k9 o5 o
  49.     }
    ( |; u6 q% z% f4 y/ d
  50. + A$ `6 n0 |# S
  51.     public function count($where = []) {
    7 E# n; w& a8 v0 f
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);% I5 Q( r7 k& _; ?) d0 s2 ^/ q
  53.         $result = $this->mongodb->executeCommand($this->database, $command);
    " F! j( q2 r) A' i
  54.         $res = $result->toArray();
    . f* Z9 j' k! d7 M
  55.         $count = 0;$ T# v! C: b# S( b' a& z0 J
  56.         if ($res) {
    - J0 G8 V7 T( J( l) ^, E9 u: I1 G
  57.             $count = $res[0]->n;0 \5 x( ~( ?# u# S; e! K
  58.         }0 x& e' t" B  ?
  59.   K! ^* [( _2 `3 R2 y7 n2 T
  60.         return $count;' C3 m2 \( n/ g/ ~' N
  61.     }
    7 A0 q1 L$ C. \% H

  62. # O! ]- u. }1 O
  63.     public function update($where = [], $update = [], $upsert = false) {7 U; v0 X9 @( g
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
    1 Z& P6 Q) ~* c7 S3 A
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    4 h5 a* W% [8 A

  66. 0 U0 v# G! U) _( J
  67.         return $result->getModifiedCount();7 d  I4 y; e: c
  68.     }
    + _0 J  w1 \6 d/ j
  69. ) Q$ c$ r! [" g3 L
  70.     public function insert($data = []) {
    4 w1 Z( N  j- y9 K
  71.         $this->bulk->insert($data);' K" Z! R) l' b3 S2 n* }
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);8 G. ?! W1 ?8 N- z2 U" u

  73. + L- j; ]$ L7 A; B
  74.         return $result->getInsertedCount();. \+ e( t2 e2 l" u& w5 C
  75.     }' t# F8 j/ E2 T0 n2 x  D# I
  76. % V  V; _; c( H  [# q( o5 [
  77.     public function delete($where = [], $limit = 1) {* J( E5 _9 \. y5 T5 G7 |
  78.         $this->bulk->delete($where, ['limit' => $limit]);% J6 P7 ~: c% I' H5 }: N0 J8 d
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);+ b) m8 e# H0 ?3 p
  80. ( d7 c9 K2 T3 O3 L
  81.         return $result->getDeletedCount();! H2 T- u6 P  {2 G4 A" }% q* M5 V- Q
  82.     }& d% [! l  I8 Y5 [- M! x5 {0 ^
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单4 c( i! Y/ p% C# m5 P
  2. $lastId = $resultOne->getInsertedId();
    $ j8 V) r- b5 U+ Z7 f+ E
  3. $resultMany = $collention->insertMany($array, $options);//多
    - Z# P1 Y/ H" \: \& E& {
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    ( g2 ~7 {4 |2 ^/ r9 t( q9 q
  2.     '$set' => $values
    6 h2 ]& z( T$ u; s, A4 O
  3. ,[- ?! @: d' `" U6 P
  4.     'multiple' => true//多条,单条false* r7 M, u2 h, E0 K0 z# T
  5. ]);
复制代码
  1. $collection->updateOne(( z( O! D* ^" @- G9 ?$ |5 ~
  2.     ['state' => 'ny'],
    4 @+ {! d+ L  @- I/ b* \
  3.     ['$set' => ['country' => 'us']]
    " [- |) w2 |& ?1 E8 \
  4. );
    + U' x% O! V" e2 B  I( A" i
  5. $updateResult = $collection->updateMany(( m6 J" T) O# f- o7 S7 w; m6 u
  6.     ['state' => 'ny'],
    " c- f. P0 R& M; R* C& E/ u! {, T$ |
  7.     ['$set' => ['country' => 'us']]
    * }2 g7 ?3 W+ h
  8. );/ `2 Q8 I- O& G/ L6 @' |
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    6 T) T( `2 E4 s. i. D
  2.     'name' => true//指定字段, f' r9 V# k0 ?. Q$ w  t
  3. ]);
    . O/ ?. s) o7 x$ q1 a/ M
  4. $cursor->skip(5);
    ' z4 x; t. j) b3 m$ L; M
  5. $cursor->limit(5);
    # [- \. L, N. h: X
  6. $cursor->sort([
    4 s# `  X+ n# d4 Y1 o' ?8 Q4 |
  7.     'time' => -1
    & Q# y% e2 [: d, F" J1 c0 o
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [/ L" s" f* W" b5 m# H; d0 e5 b
  2.     'skip' => 5,
    . d: I9 Z8 Y1 g% ]) j% q, ~, I2 F
  3.     'limit' => 5,* u( h+ c; J, n% q# d
  4.     'sort' => [
    % d8 S3 @& m/ ?4 P  H- C
  5.         'time' => -1
    # I( v* i0 @$ j0 u( H) c
  6.     ],//排序, ?, y8 K; K" C, z
  7.     'projection' => [; H( p* p) O. w( }* F- e
  8.         'name' => 1//指定字段
    & g: f. t& N3 G" V, |0 O/ A- H
  9.     ]$ H  ]4 x+ a# a( N
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [* J/ T( t. e8 @" C# B" z
  2.     'justOne' => false//删单条4 E( a4 M$ t# c
  3. ]);; T! O( f1 h% q6 y: ~* b" v
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);4 K; e1 {  C$ `4 Z( x0 U
  2. $collention->deleteMany($condition, $options);4 f) F) k9 ^. f% Q, _8 g: G+ i8 r

  3. 8 v: [3 d; B4 M  p7 K; D
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([' E2 \" P  u8 h* E
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    ) Q  O" K! n& R) F+ }
  3. ], [
    ! c% ?  p2 I0 }# f* I
  4.     '$inc' => ['id' => 1]//自增+ W" h9 |+ I" f
  5. ], [) C/ X$ I# B0 G, K& `0 ~
  6.     '_id' => 0# a' z) I. v2 Z- T
  7. ], [
    + S$ Y4 [& S) E- s( I+ n
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    . k% N* T6 J& u5 q# Z/ ?
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([
    * F/ R3 N' U' k/ @: d5 m! T5 |
  2.     '_id' => $tableName
    7 U) d8 A* X- y6 z7 [- t" x
  3. ], [
    6 h  j; a# ^; l9 p/ u
  4.     '$inc' => ['id' => 1]
    $ R6 H- Q+ K2 F1 W2 G/ S
  5. ], [
    ; I- T+ q% z$ \! B  a& \
  6.     'projection' => ['id' => 1],
    * T6 B; z: r- F: r
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER" \2 _; |4 U4 ^/ j8 s% Y
  8. ]);
复制代码

& c. m* ?; s! t" @$ y9 t1 K) N4 |6 Y5 U- t





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