cncml手绘网
标题: 升级PHP7操作MongoDB [打印本页]
作者: admin 时间: 2019-3-19 14:24
标题: 升级PHP7操作MongoDB
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。
但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。
MongoDB 驱动如果使用原驱动的话,大致语法如下:
- <?php
; e, N B% r" r3 e7 J
1 q% U) S! F/ Y2 f. Q- use MongoDB\Driver\Manager;
g9 P! J/ ?# Y9 T: D - use MongoDB\Driver\BulkWrite;
# a& ?' h& `5 N$ _+ }$ J - use MongoDB\Driver\WriteConcern;- m5 X" Q' w/ t) X8 o# ?# B% y' w! `% O
- use MongoDB\Driver\Query;
8 W0 l3 F% ? w+ o - use MongoDB\Driver\Command;
0 t% w; ^& W, i# b# A n' Z7 [ - 6 D+ }6 V4 a; S& e
- class MongoDb {$ U8 \ ]+ x7 p3 ]- S p
5 {' U$ E# G. h- protected $mongodb;1 ]& J0 d1 V" |" T0 f3 N4 b! v
- protected $database;( U3 s/ {2 r0 E$ T2 x! l. d0 I
- protected $collection;& ? k9 I5 ?1 y1 Z7 ?
- protected $bulk;. V; L) L+ i! l r
- protected $writeConcern;: M! _0 I$ p4 \9 e; h
- protected $defaultConfig7 P8 n9 Q# q) U! w- P |! L
- = [
( ~6 b% H+ w. x- U8 l* Q - 'hostname' => 'localhost',
- X5 c' @5 i F- R - 'port' => '27017',
5 _6 d. f5 H: Q4 T - 'username' => '',
: h# }$ ~. n0 P/ u( Z - 'password' => ''," X( _. s# |7 g9 \/ n* w5 V
- 'database' => 'test'
7 K6 N" a }, y. j# N- x$ N - ];
8 \1 d/ z9 |" Q o, \ - ( T u' ]4 a& {( |# f8 W
- public function __construct($config) {
3 G. `! m: H# h7 \% O - $config = array_merge($this->defaultConfig, $config);
1 ~5 X: ]0 `. o- v - $mongoServer = "mongodb://";' X F: h! @. G* f+ d# q
- if ($config['username']) {$ s7 q7 Y& M8 T
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
# F! W# w( ~% f/ P: m - } c% p. O. @8 C
- $mongoServer .= $config['hostname'];
1 \) }7 T3 V$ o) [0 y - if ($config['port']) {5 {; G+ k+ O! w7 \0 i1 n1 p0 l( O
- $mongoServer .= ':' . $config['port'];0 L) O; [" q4 k; \) ~& ^
- }
2 Y3 w4 }) H4 E - $mongoServer .= '/' . $config['database'];# P2 i+ y8 U5 {1 j7 j( w9 y) h
- # k: o7 \9 _- v" k# q
- $this->mongodb = new Manager($mongoServer);
+ Y2 [- H; m2 q& ~' R9 |" [ - $this->database = $config['database'];
9 Y1 d) C' V# {+ ], y' s - $this->collection = $config['collection'];
: o9 b1 [4 N8 c - $this->bulk = new BulkWrite();
7 ^4 j+ @+ p9 a7 T o' p - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
( Y( m$ w; F' d1 Z g) i7 H - }7 T7 d, f" C* o( r8 V
- - J+ `& b& \' Y' K. g
- public function query($where = [], $option = []) {
6 J+ u* Q' m4 {; f" V' ]$ K; } - $query = new Query($where, $option);
9 r: f) Y- \+ i( x, G/ r - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);% |4 E4 F! M9 R1 y% V ?0 e' R
, z3 U( b( @4 i% Z7 d4 r- c4 x- return json_encode($result);
! S' P2 q$ c2 g' y! l - }
- R" b# |9 a6 a ]' r - $ M: s. r! L" Z& l/ k+ r6 e
- public function count($where = []) {' ]+ T B6 z* J1 W2 L$ _, y
- $command = new Command(['count' => $this->collection, 'query' => $where]);/ b0 s! d5 U% ^* }
- $result = $this->mongodb->executeCommand($this->database, $command);- ?4 h' h& E' e# Y
- $res = $result->toArray();' E+ Q% v& W$ X7 i4 ?2 P
- $count = 0;4 [9 |3 ]9 \4 L% F+ `1 m$ u
- if ($res) {
( i5 Y, ^6 [! c4 X/ K$ I3 t - $count = $res[0]->n;, v2 a' Y1 y) Q) _5 J( S& V( [
- }
" X3 j0 ?/ Y: T - 7 Z6 m. U: N' H+ I% g2 Y1 g7 i
- return $count;
$ | t, m( j# v4 P4 X1 J+ _" w3 j- b - }
; e+ b! |4 ^* ?) s, V3 u
# E/ [% D: a$ U7 ~) x6 N4 a2 i5 ?- public function update($where = [], $update = [], $upsert = false) {
7 k1 @4 Z) E( P - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
3 }0 F: Z. q! Q6 T - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);# }4 U% |3 L# @2 v7 k. [' l. o
- $ S( n" Y4 z" i+ I
- return $result->getModifiedCount();% b9 I$ { Y- H5 Q, c: F7 B
- }. m. ~8 l/ r8 H9 i% \+ S: y5 x
- `: o- a7 s7 J- W- ^
- public function insert($data = []) {/ H3 R$ } p+ q3 n' z
- $this->bulk->insert($data);6 r' G$ H. u0 W6 d% y! n
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
9 w, J; r1 v' C& u, }9 f
9 \! ^' [ G6 B- return $result->getInsertedCount();/ C8 i L0 u& @# a3 B; C
- }
- M3 I! W* h' l! H9 ? - 9 @, L! d& R1 R( m, J
- public function delete($where = [], $limit = 1) {( G( g; X) a" z( @; f7 J2 {9 d
- $this->bulk->delete($where, ['limit' => $limit]);
' h4 a# u- K* A6 X' j0 F# i( v - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);5 L$ ^8 Z8 O& ]) C& j$ i" }
( M0 r& X! L8 A- return $result->getDeletedCount();
& _2 L$ V* ?; [6 f: T( s - }- z9 y' x f7 x+ G" p* y) r+ F
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原
8 ?) Z8 }1 R" S3 c; G0 p% s' H# a
2.新增- 原
4 [( D$ Y3 ]4 h6 o" n4 E
- $collention->insert($array, $options);
复制代码- 新
$ I5 ^5 _$ I* D1 p: t4 l
- $resultOne = $collention->insertOne($array, $options);//单
6 T2 k3 H0 L, u: _9 t - $lastId = $resultOne->getInsertedId();
4 [/ I) z5 E( U: S" p3 P7 x - $resultMany = $collention->insertMany($array, $options);//多. L* i \9 h+ i/ |
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [; y( x2 s3 H/ \3 g2 i) @
- '$set' => $values R6 {8 {* D5 W p! y' I: U
- ,[ w9 e2 c! R, d# I _. M$ g+ H* {$ r
- 'multiple' => true//多条,单条false" S* O; a. U1 L% C# G9 m- E
- ]);
复制代码- $collection->updateOne(
$ U3 B$ w) {; W3 C; @' o - ['state' => 'ny'],$ Y+ s. ^' @( m- P' n& e- V) T
- ['$set' => ['country' => 'us']]
/ C: ^3 P: g% `3 ]2 y8 R8 ] - );3 m% n6 z& ^; ~" p
- $updateResult = $collection->updateMany(% x) D: n' e5 U/ p& a; d
- ['state' => 'ny'],9 }* \' z( ~5 V; q; v# }4 E: i4 Y
- ['$set' => ['country' => 'us']]
# r; {! y3 i( t ~. m7 ]$ ^7 F' d - );$ x1 X4 S* Y1 }
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [2 \( o7 p4 D( L: n4 V& a2 N
- 'name' => true//指定字段* i: W! l- j9 a
- ]);
9 |4 e$ S6 Q" w6 ~# A - $cursor->skip(5);. O( X, {( ~! N5 }2 B2 R
- $cursor->limit(5);' g0 `" ]& V& v+ g; N
- $cursor->sort([) L; o" n4 _6 r3 g8 |8 @& r+ K
- 'time' => -1
" V* H& m8 `# J2 j, W/ O( [ - ]);
复制代码- 新, H* |7 Y' l3 }1 k7 J( V
- $cursor = $collection->find($condition, [ O( y. z. r4 o, [* F. ^+ h
- 'skip' => 5,
% y6 W1 v' V7 l! o2 u. l: v - 'limit' => 5,( X3 v$ i3 f W5 }$ [' }) B
- 'sort' => [) z' y- \! V7 l0 j
- 'time' => -1# y; S! r/ c3 \3 J
- ],//排序/ n& K, m7 D( X; r
- 'projection' => [
2 n1 x/ c, Z+ k7 V; `8 _, \. c - 'name' => 1//指定字段) x) t& Q$ L8 w6 j7 m
- ]
7 P1 V) U C6 t0 N- _2 L1 |. f - ]);
复制代码 5.删除- 原
: Z6 p; {7 q# A9 L1 I, R1 p3 [
- $collention->remove($condition, [- u$ y5 R- E' ?
- 'justOne' => false//删单条% p4 G. }* T7 ^5 @6 f* [
- ]);: J1 A P$ Q$ J0 l3 S
- $collention->remove([]);//删所有
复制代码- 新) F/ w0 s0 H S. y1 a8 W. j
- $result = $collention->deleteOne($condition, $options);5 _8 |; @4 j, y$ H1 c$ ^ H( ]
- $collention->deleteMany($condition, $options);
3 {" e f! ~$ Y
9 X' R! q; L4 g) B- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
( m" u% ` [% n. Q% P' B$ \3 d - '_id' => $tableName//我在自增表中用其它的表名作主键
/ y+ T4 |3 E }: L - ], [
4 c, z: `3 ~+ [; `" x8 x, O! N& w - '$inc' => ['id' => 1]//自增2 O6 t+ N3 k/ i
- ], [ `1 l# ^) A! s: P1 S6 q+ Q
- '_id' => 0, L$ ]# Q) s9 ]" P, K% B
- ], [8 D0 ?- _3 q0 h# Y* a8 ~# S
- 'new' => 1//返回修改后的结果,默认是修改前的
4 h4 A( z0 @$ J - ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([# R6 k4 w+ i# |$ E$ T
- '_id' => $tableName, Y- _! `5 v5 A6 q
- ], [
1 J5 ~; E/ A) t! m - '$inc' => ['id' => 1]
6 F* [ j+ z& z; |$ A H* L - ], [
! j* y6 [" ^( W* S; k0 V - 'projection' => ['id' => 1],
9 R7 k7 T7 Z: [. R8 A6 d - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
0 n$ s7 j4 K; c2 w; @5 t5 T - ]);
复制代码
/ Q6 V0 ~. U8 n& ^+ `$ h$ l6 Q* U) @2 f
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |