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
    , _: E, q3 J' h7 W! ~5 \

  2. ( H% z2 B  {% ?2 s
  3. use MongoDB\Driver\Manager;: T1 ~# N6 S3 C2 M' u- ^% ]; n
  4. use MongoDB\Driver\BulkWrite;( f( q0 x8 [8 e. o. Q
  5. use MongoDB\Driver\WriteConcern;( j. h8 ^" U# v" e
  6. use MongoDB\Driver\Query;
    & X1 Y! N. p8 O6 b0 b! U
  7. use MongoDB\Driver\Command;. W9 q8 g$ h, I6 g0 j

  8. ' N: }7 S( L, A! Y( B2 \5 x
  9. class MongoDb {
    0 D5 [* W  a. N- S8 e* a6 |

  10. 6 W  r5 `  z' u
  11.     protected $mongodb;
    " O' z. L) d; I+ G" j
  12.     protected $database;
    2 x, ^% k2 A, U4 z  c3 |6 u
  13.     protected $collection;5 k" L7 T- T# `, L
  14.     protected $bulk;
    5 x, D: m1 x  T
  15.     protected $writeConcern;
    " P9 `/ z' \: V8 z  D
  16.     protected $defaultConfig
    - z2 |# \: j2 C# F" B! k
  17.         = [
    - e& X  F% i9 ?5 C
  18.             'hostname' => 'localhost',  {, q2 G$ Z) ?2 T3 J5 D# a
  19.             'port' => '27017',
    ( T. z4 X0 D' L4 D  C
  20.             'username' => '',
    , [0 \# h$ |8 b  v# }
  21.             'password' => '',
    6 @5 ]1 J2 G) H+ P7 T$ i* W5 E
  22.             'database' => 'test', \' D/ ?1 E! }) d5 w0 w
  23.         ];
    . G# m6 m+ F8 E3 K0 r
  24. % p% i; {  I1 @  U2 D) R
  25.     public function __construct($config) {* L5 j" {3 j/ i
  26.         $config = array_merge($this->defaultConfig, $config);( ]5 u. p" w! }- h, K9 x0 C1 c
  27.         $mongoServer = "mongodb://";2 L; o0 E, a4 H, v) B
  28.         if ($config['username']) {
    , T- \' f: Y5 ^/ f7 D4 H  {/ Z+ X7 A
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';2 c7 y$ e+ f+ f; Q
  30.         }
    ' A% P- ]$ y& X# l* Y2 c
  31.         $mongoServer .= $config['hostname'];
    ; l3 [8 ~6 y3 X4 d0 g
  32.         if ($config['port']) {& D+ G' F& @, \3 H6 n, B
  33.             $mongoServer .= ':' . $config['port'];
    ' y) G9 `/ X: H3 ^% q1 d  }- j1 e* o
  34.         }7 y  w! v4 B( Y  L" P
  35.         $mongoServer .= '/' . $config['database'];! y/ h' D' P# L

  36. 4 _7 A1 a# {7 ~9 v0 m# J, u
  37.         $this->mongodb = new Manager($mongoServer);5 _+ c) ?6 ?9 v
  38.         $this->database = $config['database'];
    ; T, q2 b" ~! k" {. G/ S0 J
  39.         $this->collection = $config['collection'];
    * w  [- o# x3 H' i2 f' [' c3 u' c3 m
  40.         $this->bulk = new BulkWrite();
    % e- k' B, o* J) d; Q; m. H2 S
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);8 J9 R. A! j) ~& f
  42.     }
    ! a& ~# M& _4 H/ n* n
  43. 1 \$ p- e% u% A  Z
  44.     public function query($where = [], $option = []) {# [2 x- t# |+ Z0 o, M+ U0 _" p
  45.         $query = new Query($where, $option);# {6 H& T) s$ y! ^
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
    6 Q2 i2 R& i" \" z$ X
  47. , }! y7 H" z9 }, N" R% T8 G3 C  y
  48.         return json_encode($result);
    2 A3 J# y1 n$ W$ x7 T
  49.     }
    ; `4 K' \2 N8 J' I
  50. , b' a4 ?+ S9 i# C3 N0 L) u
  51.     public function count($where = []) {
    # ?: B" F; [2 I( [: c, q/ R
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);5 J+ k$ N; i5 e2 t) n
  53.         $result = $this->mongodb->executeCommand($this->database, $command);. L: }3 n* Q! r5 n. ~, V
  54.         $res = $result->toArray();- z; U: L9 n; f: t$ d6 B( G3 y' |& r
  55.         $count = 0;
    1 s4 C" A8 U+ R7 d; E* ]
  56.         if ($res) {
    + @! K5 K& `1 O4 X/ }
  57.             $count = $res[0]->n;
    - l5 c& k3 U7 g: ?* o9 r
  58.         }
    ) Q  Y3 ]3 c4 o; M! I5 V& U. C

  59. # R& `" F- N9 ~0 C
  60.         return $count;
    # N) g" U  K* q& U0 S4 A
  61.     }" Z6 {) t; }& v/ K
  62. 1 S6 U6 j% O9 l/ f+ L- m5 u
  63.     public function update($where = [], $update = [], $upsert = false) {
      j% I* a, W+ R) ?7 [7 Z$ ]! ]
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 ~+ n( V# R. ~/ O% r+ o% Y
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);3 z2 ~: u* ^" }

  66. / N' S) {/ f$ _
  67.         return $result->getModifiedCount();9 {" b% y+ _# S1 n! ]# Y- c' A. b- l5 P
  68.     }3 H. U) |# G" C) w

  69. & N5 _4 ]- L) V9 C/ q0 D0 O
  70.     public function insert($data = []) {; R  {$ B" _7 b. a7 h9 B0 r
  71.         $this->bulk->insert($data);
    % ~* B7 @- I5 v/ \3 P4 h
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);# \8 u- o  \  B  O

  73. . L4 Q2 r; D0 ]/ H9 A7 U
  74.         return $result->getInsertedCount();
    ! `* j% J) x# V! N7 O. Q( s
  75.     }" ?, h- p) o' k: ]& N# c8 s1 [" X% j

  76. ' D+ [* ~3 y# J! u
  77.     public function delete($where = [], $limit = 1) {/ o# G4 {/ x* O6 j
  78.         $this->bulk->delete($where, ['limit' => $limit]);: Y- J  b  Q: q. ]: W* G7 _; ^
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    $ o. y  k' w6 Z7 p
  80. . t8 y; ~2 |# I& u1 y$ z& {
  81.         return $result->getDeletedCount();
      ~5 u& G: A5 ?
  82.     }
    + @6 u0 v4 z: F
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  1. new MongoClient();
复制代码
  1. new MongoDB\Client();
复制代码
2.新增
  1. $collention->insert($array, $options);
复制代码
  1. $resultOne = $collention->insertOne($array, $options);//单
    . s, m) @; j, S" @7 k( ^5 s  l
  2. $lastId = $resultOne->getInsertedId();
    - c, B0 O0 A0 y" v5 P
  3. $resultMany = $collention->insertMany($array, $options);//多
    $ d# Z! O) S5 H1 h. D  c
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  1. $collention->update($condition, [
    4 x7 \3 |3 |" T! `3 O
  2.     '$set' => $values
    4 F, a+ g5 n0 x# m& J
  3. ,[7 j/ f$ S1 S* _: P* y
  4.     'multiple' => true//多条,单条false
    ) T3 F4 f) t: G4 X
  5. ]);
复制代码
  1. $collection->updateOne($ g# P6 e9 H5 Y& X1 ^2 ~' m. A: F
  2.     ['state' => 'ny'],
    . z; `8 J6 ~4 [; A+ y; Y3 b2 @- w
  3.     ['$set' => ['country' => 'us']]/ R8 \9 Q4 S" C/ {( ^
  4. );
    7 `) D; y% w& B7 m' F
  5. $updateResult = $collection->updateMany(
    # z* O9 D; N0 L; z
  6.     ['state' => 'ny'],
    ( M8 I9 K3 ?8 j9 z  r+ r% c( d
  7.     ['$set' => ['country' => 'us']]
    9 }, D: `5 S6 l4 L/ j$ T
  8. );% j& V9 }( y- F3 W  y
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询
  1. $cursor = $collection->find($condition, [
    7 _+ [$ o, ]8 j# j
  2.     'name' => true//指定字段7 b- D3 Z+ _* P1 w$ L
  3. ]);
    ( W% c8 U8 J) Z
  4. $cursor->skip(5);
    / I; V% ]' t4 |( h0 m" o5 n% \. R
  5. $cursor->limit(5);
    / }+ o) Z8 t6 A( h7 k$ I/ M
  6. $cursor->sort([
    ( y, g; g: y. m/ V6 E
  7.     'time' => -1* S# `# z7 q  F' c! l+ X" x
  8. ]);
复制代码
  1. $cursor = $collection->find($condition, [
    . [, _; P. t/ i5 t+ a
  2.     'skip' => 5,& y. k; T# J3 H
  3.     'limit' => 5,  k+ G: u1 j" s" D8 I, w3 y; X
  4.     'sort' => [7 p/ k  E& L: f+ R! W2 _
  5.         'time' => -10 G( J  t8 z# j
  6.     ],//排序" T7 b* f- Z, b/ }
  7.     'projection' => [
    % o& f% m. x; G" @
  8.         'name' => 1//指定字段
    + j1 E# e% Y3 t2 V! Y4 |
  9.     ]8 O* {  a. q" r+ U
  10. ]);
复制代码
5.删除
  1. $collention->remove($condition, [
    , H8 E' v. b  o* t! B
  2.     'justOne' => false//删单条
    $ r# P8 q, u) F* z4 ?
  3. ]);
    : |7 d2 q5 I4 j8 w5 a% p" o7 ^
  4. $collention->remove([]);//删所有
复制代码
  1. $result = $collention->deleteOne($condition, $options);; w, B: p" h  R1 V$ L( R2 Y
  2. $collention->deleteMany($condition, $options);7 O; ?, R4 s, T7 `* L3 w! B' V9 o7 S

  3. ( V$ r& ?. o/ L* W1 `' F# l, F
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    9 X" A, t0 s" o1 [( ?' \1 J
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键
    ! X5 E  L- {6 I  A8 x2 y
  3. ], [
    8 i, m& _" T$ ~3 U  d# x
  4.     '$inc' => ['id' => 1]//自增! s$ r8 @$ j5 s' a1 B) k. H4 Z! W
  5. ], [
    6 }- W, |$ N* j! a2 k
  6.     '_id' => 0
    7 F# m  n' O9 h4 m3 Z" E- m
  7. ], [. t5 I$ q# _6 F1 X! `
  8.     'new' => 1//返回修改后的结果,默认是修改前的" @3 J3 f- ^  \6 B* |# ]  d7 n* s- H
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([) C- }% u0 x7 u1 u/ U' m
  2.     '_id' => $tableName/ F) S5 f/ P- W/ ^- h5 [
  3. ], [; x7 }* _7 f7 g* Y- @
  4.     '$inc' => ['id' => 1]; O' A! V9 n* n. R: P
  5. ], [. T/ ]; @6 n6 m
  6.     'projection' => ['id' => 1],9 I1 @+ _0 B( G7 T4 y; u. D* I
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    - n( B' e8 X: H. Q+ n
  8. ]);
复制代码

" h9 i# h3 k8 T6 G2 o/ Z$ L2 n8 }. ~% U' K( I# w: Q





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