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: `5 h" I9 D9 c% Q( ^  D* ~
  2.   x" ^2 K2 H" ]0 |* p
  3. use MongoDB\Driver\Manager;
    ' y* z6 C; i! \
  4. use MongoDB\Driver\BulkWrite;
    5 u: w1 ^  }* {" W  |& ?; @* F  M
  5. use MongoDB\Driver\WriteConcern;( l+ `* t. ]- i2 w6 I* R& {
  6. use MongoDB\Driver\Query;2 M7 m# Y2 {$ ~/ N5 Y
  7. use MongoDB\Driver\Command;
    + P* ]! @4 g- W$ E0 A: z& g

  8. " J; H( R6 h2 U* y! x/ k
  9. class MongoDb {
    * l1 m, f0 @# s. ^. }6 e
  10. # ^$ x1 e, {; k* v1 r- l
  11.     protected $mongodb;
    ; M& a2 ^8 `, Y8 ~- d2 V* g5 R1 ~4 ?8 E
  12.     protected $database;" R. T! W+ o& l) F: e; W
  13.     protected $collection;
    , m2 Q1 e, ?$ Z# ~4 E/ K% |
  14.     protected $bulk;. q5 A( q& |0 }. c: |
  15.     protected $writeConcern;4 z- ~- t" Z' ?; t, O
  16.     protected $defaultConfig
    0 D& [" A1 b  V2 G! _+ [( x5 u+ M
  17.         = [
    " c* o  Q( H  Z9 E2 L& Z
  18.             'hostname' => 'localhost',4 T7 _' T- Q/ Z0 Y7 d" g) B
  19.             'port' => '27017',
    7 E4 z. C% ?" q3 P/ v" k
  20.             'username' => '',' M4 h  Z7 ]7 C: G. G& a
  21.             'password' => '',
    7 p+ _3 L1 W, _  l+ h
  22.             'database' => 'test'
    * q7 ?5 v* I6 p& D( U
  23.         ];
    - ]; L5 f- x3 u2 ]" `2 X* S; x

  24. + T9 _  P+ J8 s% Q6 ?2 ]+ `5 w
  25.     public function __construct($config) {
    1 O+ r4 z6 F! ~3 r4 C' L! ?+ |* p
  26.         $config = array_merge($this->defaultConfig, $config);
    ! _- L) s+ |% \3 X& U
  27.         $mongoServer = "mongodb://";& i: ?# C, j. Z2 y
  28.         if ($config['username']) {, y/ a# F2 @% y% L8 a9 S: v$ M
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
    3 @0 q  c7 O. k  }) J/ [
  30.         }
    , L, {# m$ s' q( b/ }" L4 _: `
  31.         $mongoServer .= $config['hostname'];
    1 C0 \2 {/ H  |0 O, P7 h
  32.         if ($config['port']) {' f# `* a8 b5 z5 D7 m; m& X, Z
  33.             $mongoServer .= ':' . $config['port'];
    , ]- m* i+ {5 H* Z' F
  34.         }" R' A- R. ^# v2 f5 F
  35.         $mongoServer .= '/' . $config['database'];
    , i. N) y& i; t9 z. V$ z6 k
  36. ( P) L' |5 T5 O" W: v6 {% j
  37.         $this->mongodb = new Manager($mongoServer);
    7 o4 h% G, u& |& p5 C! l! {
  38.         $this->database = $config['database'];
    % {) T) C; e7 ^7 @3 L$ x; f, q( h
  39.         $this->collection = $config['collection'];
    2 H! r1 @1 i- V& W8 S; T# `% e
  40.         $this->bulk = new BulkWrite();
    % s- m% s9 A, b' O% Q8 |, H
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
    2 f9 Y% L  s+ ?$ V' m
  42.     }$ C  m: q9 d* T

  43. / @$ Q# d/ z9 m! N% b1 V# t: W- a: y
  44.     public function query($where = [], $option = []) {
    1 f7 X* u9 G$ @6 v# ~$ A# x
  45.         $query = new Query($where, $option);2 ~+ ?& b5 U" v9 }3 `- ~2 H1 a
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);$ K# u+ M+ C; S" }, m

  47. ) b% E. h8 p7 l1 w
  48.         return json_encode($result);1 P6 u1 {$ |4 c+ c. s1 y
  49.     }
      V3 g. `7 a( L% d$ C
  50. 0 M5 x1 C2 A5 n% \" M8 _3 ?
  51.     public function count($where = []) {- `- N( U4 q0 z$ s1 `% U7 v
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);  Z5 _4 K' d% a8 P
  53.         $result = $this->mongodb->executeCommand($this->database, $command);3 y) g/ j) K  Y& p" N
  54.         $res = $result->toArray();
    0 t" f& P3 }$ S1 k
  55.         $count = 0;
    4 z+ _; Y) I. r# e! |
  56.         if ($res) {; S/ h8 F- j2 W) y- q
  57.             $count = $res[0]->n;
    " s7 ?% B8 k8 ?6 I! A4 K8 [
  58.         }- \/ o' E7 l4 w

  59.   h; _0 K. r2 n" `/ X3 G1 B
  60.         return $count;) ^6 u4 }% O! w$ o% L' v
  61.     }
    & w. Q6 S7 _# [. @  z# G: l! q/ a

  62. 9 R& i- h8 W. r) i
  63.     public function update($where = [], $update = [], $upsert = false) {
    * j1 a1 p' p8 N* I+ j
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);  V+ }  T, @8 _" _
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);- F2 ?; Z8 X9 U

  66. . {6 z/ }1 h6 W4 c# E- ^/ Z
  67.         return $result->getModifiedCount();
    " M( I1 v% s9 }7 u2 @) `" |
  68.     }- x' Z2 N3 ]8 L" h

  69. 1 ?5 e* t3 A; w0 L9 ^5 p$ `
  70.     public function insert($data = []) {
    2 X0 |" q  c( E: m. b8 a5 B
  71.         $this->bulk->insert($data);
      @; l# b, W6 z4 V" s  K& P
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);. h; B7 M- }; |* `, ]

  73. 5 J9 |% s, V0 t: k. k0 U+ I( p
  74.         return $result->getInsertedCount();
    0 j* R+ _1 z: s8 y
  75.     }
    7 e4 D: O" b! ^# \+ F( s
  76. 7 J7 ]. Z, p" p5 }: o3 B
  77.     public function delete($where = [], $limit = 1) {) _% F  K+ x* y6 _
  78.         $this->bulk->delete($where, ['limit' => $limit]);  N5 q# @# X- M( J) B' }
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    % f# O( F4 O0 \
  80. 5 y7 @. ]. A. o* Z$ Z8 Y7 G9 r
  81.         return $result->getDeletedCount();
    8 b$ {) `  h  T' B
  82.     }
    9 U) G8 Y" U/ e4 t  u
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单
    $ [% ~/ ^  B/ L$ F9 T
  2. $lastId = $resultOne->getInsertedId();
    2 h8 _1 }8 u8 P' Z0 @. V
  3. $resultMany = $collention->insertMany($array, $options);//多7 ^6 L4 l9 p6 U' }+ o2 v( U
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    6 ]. g$ p. C4 {1 t' u. n1 e
  2.     '$set' => $values
    ' M+ t4 B; p4 ?& n/ S
  3. ,[' V: q, G! w% o8 ?# ~2 D; E' n! C
  4.     'multiple' => true//多条,单条false1 {% M/ d/ G2 E/ e# l% J! s% x0 J
  5. ]);
复制代码
  1. $collection->updateOne(
    9 p& p% e* D" H* D/ G. s6 U
  2.     ['state' => 'ny'],/ ^% i! O9 j$ h7 z+ e. K) V
  3.     ['$set' => ['country' => 'us']]6 c$ N5 u/ V' x- _5 f! Z
  4. );
    7 I# w! [$ a3 ~: v! v+ i
  5. $updateResult = $collection->updateMany(2 \0 v+ K- J3 L  j, A$ u
  6.     ['state' => 'ny'],0 q2 X/ N$ S4 _
  7.     ['$set' => ['country' => 'us']]
    1 M% _; J* u6 Z9 Q
  8. );
    * J% A% _( C7 O) p8 B. t
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    " t9 {, z" x) k( P# Y+ N4 c
  2.     'name' => true//指定字段$ j0 N9 B3 ?7 \# n8 Q5 n4 A
  3. ]);
    , q% Y( u- P* m( }- r
  4. $cursor->skip(5);
      d. \1 w, x# `8 Y  C5 s
  5. $cursor->limit(5);
    . F$ A$ B0 q2 L2 P
  6. $cursor->sort([
    . j& t$ Z8 D1 Z6 a5 c- Z
  7.     'time' => -1
    " g' ?2 M* \* ]/ b/ Y+ w! g
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    $ i' [0 P( o" f. d0 Q! [9 K
  2.     'skip' => 5,( }' y0 y7 c: B/ }
  3.     'limit' => 5,
    ( O5 y% d% M6 K* O3 R  C
  4.     'sort' => [$ R% M. R0 b" b) T' {: T- I
  5.         'time' => -1
    , a0 ]% X; R# `( R( r! k" d) U4 G
  6.     ],//排序
    ; m$ ^9 ?. d9 _5 `) n2 N
  7.     'projection' => [' S! G+ @* y. G- @% l
  8.         'name' => 1//指定字段
    . i4 n  a# C5 k! `5 k0 i- m  Q
  9.     ]! s4 `3 w* X4 e- @" F% l' h
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [2 J+ o2 Q, _8 k# H
  2.     'justOne' => false//删单条
    " ?+ x: q6 Q9 g: U8 D
  3. ]);( q8 c2 N" {  J3 L. n
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);3 X8 ~1 a8 F+ c3 {, O% K
  2. $collention->deleteMany($condition, $options);8 e7 }! A% E+ E
  3. 1 o$ K4 p/ D' L
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([* I$ {: d4 [& q" Q
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键& \7 M% B% a% P" g; ^1 m! ]: C& V$ o
  3. ], [' |! s5 d0 I: C1 W" m- O
  4.     '$inc' => ['id' => 1]//自增
    + |% X5 W- S( v% o
  5. ], [
    ; \& D' P& {6 m
  6.     '_id' => 0* C/ H' S# V9 Y& z+ `
  7. ], [$ g3 x% a$ `" m5 u1 V! k9 d0 e* @$ ^
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    $ W8 g, s2 u) F( q
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([0 ?! U7 X' B/ c6 @: r+ K3 ?
  2.     '_id' => $tableName- d" {' ^$ a! a' x3 s' \
  3. ], [/ a. Z3 w' @* w5 F
  4.     '$inc' => ['id' => 1]5 i1 e/ b% f2 P) T( n+ x1 t
  5. ], [
    . V, ~2 T; O8 `9 E  \1 n) m( u0 ^
  6.     'projection' => ['id' => 1],
    ) q8 Q9 Z) d& R6 `
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    ' L0 S( K5 u$ E0 }! z* t* w
  8. ]);
复制代码

, X5 b, H3 z  c: z& J8 _
) v$ w' Z* v# o' j




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