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 驱动如果使用原驱动的话,大致语法如下:
- <?php0 |1 t6 ]" N* H6 @4 x0 N. i
$ x* k4 f9 c* ]; Q P: k: Z) g- use MongoDB\Driver\Manager;
0 v4 R2 _ [- h* C$ y - use MongoDB\Driver\BulkWrite;
* B5 x1 M( D3 b# P1 E$ Y - use MongoDB\Driver\WriteConcern;$ C. }4 j0 O5 O3 H2 t! ?5 p/ f
- use MongoDB\Driver\Query;
\) C, @" u0 h# u4 C' t( `3 u e/ i2 R - use MongoDB\Driver\Command;8 W$ o; {& l! w, ~6 ^( z0 v- a( t
) q' d2 S/ J9 W- class MongoDb {# h4 | I5 C" V& x7 O' d- H
- ( ]. K* C4 @8 y' i1 S$ v& X2 g! S5 Z
- protected $mongodb;9 a/ i* P3 I2 y( y
- protected $database; u+ P$ A- g }" `
- protected $collection;& E5 G( E. q% ~- q
- protected $bulk;
# F; H* {. v3 {* X. h - protected $writeConcern;3 d- v2 j9 Y, F; h( p' U' F
- protected $defaultConfig
4 m8 O5 m. ~" x( f! H2 } @ - = [
% v; C: |3 q. G1 w/ K - 'hostname' => 'localhost',
+ b3 V* K/ ~1 T% O; n, ~ - 'port' => '27017',! Y w* S: ^1 D; \# l; P
- 'username' => '',
" Y$ q1 Y4 g# _& q5 x - 'password' => '',
2 x, X1 P3 P( v - 'database' => 'test'
$ b' T, W5 j5 D% u/ {6 X) S - ];
r& V4 U) _/ U. T7 M
5 V- r- A* B0 S* m4 _$ U- ~* u- public function __construct($config) {
2 d* c& P5 k& Q0 {/ u& I; t - $config = array_merge($this->defaultConfig, $config);
( B4 ~7 h: e' F) Q: ?. D - $mongoServer = "mongodb://";
" B, J; Q# ~2 C! s s( h: P - if ($config['username']) {
/ f% F, M: I; H/ V' S4 k - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
2 P" c, `; q; m' t7 n+ j4 e# w- n - }
! g. F. B- Z8 t2 Z% m9 \ - $mongoServer .= $config['hostname'];% s4 x. A: _1 p6 n) M
- if ($config['port']) {
8 | U. i/ M4 U+ C! y1 r, d - $mongoServer .= ':' . $config['port'];
( E3 e* w6 Y" _( E! v0 C7 H @ - }
7 l0 m) u8 T5 d/ d7 A. S - $mongoServer .= '/' . $config['database'];
: h, h5 q6 s6 l' u2 U
1 k `5 q7 r8 e/ r' X: `: L& c- $this->mongodb = new Manager($mongoServer);
7 n* `& W2 T" v, h - $this->database = $config['database'];; {7 o+ C4 D5 s
- $this->collection = $config['collection'];" c9 ~. ?3 h# K% W- d
- $this->bulk = new BulkWrite();% d8 s" k8 J6 x( O: ]( h' t Z5 D
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
: W l2 C6 d- n% U6 t1 Y9 l1 m - }" l# Z* Q6 N% K4 ~- Q+ M
& s# w8 W' D0 V8 h# `1 X- public function query($where = [], $option = []) {0 V, P& a5 T) g7 J9 p7 T+ j! l8 i
- $query = new Query($where, $option);+ M2 c; t; E3 @/ R
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
- u! g9 v9 U; ^& Q: c
k+ w* u) f" }( S- return json_encode($result);- \+ E0 |2 R; K7 ]6 [
- }
& L: M8 g* g* h5 u0 }) ^/ ?; L - : @& {3 ` o0 a: g. C- y( Q1 [: L
- public function count($where = []) {; }. u( E$ i& f- t
- $command = new Command(['count' => $this->collection, 'query' => $where]);8 C& W% P/ K; ?- W
- $result = $this->mongodb->executeCommand($this->database, $command);3 |- l" I2 p! j2 n8 }9 [
- $res = $result->toArray();; J; w' Q( u' u
- $count = 0;& N o4 v; y# t
- if ($res) {
3 s, ` M) x7 P/ z - $count = $res[0]->n;" c. j6 y7 k0 D8 b* y
- }- V9 Q6 L6 N2 p! Y& A
- 9 I- u, u/ p m! i' \
- return $count;
" ?9 f% I9 u8 Z3 G' }% U - }! ]% t; M9 H+ e
- - O2 t1 ^: B; M& G
- public function update($where = [], $update = [], $upsert = false) {$ R- m8 `& k; v& f: x# Q% c& j
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);7 ^/ R$ z6 s- Q" v& S' D: E
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);: b- V6 r+ K3 p( q
# k, U c: @- D. a- return $result->getModifiedCount();
/ J# d X- T! D) P* r3 _0 s - }! ^$ A. p9 D1 z7 Y& F9 C
- ( j, p4 [; e# q3 [+ E) M6 q; i
- public function insert($data = []) {
4 F3 L4 {" r' Y z/ L) a6 B - $this->bulk->insert($data);
; @- p8 {) l7 X. Y5 D; P. }. U - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
* G1 m8 M/ [$ e# D6 y$ {3 i - " L9 _% }# d; {- n/ L( |# k9 R4 c8 Q. J
- return $result->getInsertedCount();5 e% e* R- g8 H& W* ?) \* J
- }
+ I8 }& o5 f* _9 Q - r4 @% N; j8 f- n7 O
- public function delete($where = [], $limit = 1) {
4 r2 y6 z# i, O - $this->bulk->delete($where, ['limit' => $limit]);% }5 v: T6 F" |
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
4 S9 |/ S: ?4 ^- @- x, Q
4 \1 x h5 Q% F7 Y3 R* t, L2 m- E- return $result->getDeletedCount(); @) @$ B3 Y% n" N/ K; D) s
- }+ N' }! v* _/ q% p0 r% E$ x
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原6 R2 T' q% v; `% l+ u' L8 w
- 新6 E4 ?5 [' n6 b8 ]( N& q2 @3 r% B9 N
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
# s: @7 Q& e6 J - $lastId = $resultOne->getInsertedId();$ q; G2 |0 e4 x4 e" o$ h
- $resultMany = $collention->insertMany($array, $options);//多8 O% N; x+ l1 a! R5 Z( n; Z& c
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [! K4 f* n2 H/ G! }( J" }: ~" h _6 s
- '$set' => $values
; X' Q z3 D! U6 m9 | - ,[4 S3 J0 V* E$ w3 c
- 'multiple' => true//多条,单条false6 b+ q. F0 Y* [+ a3 S8 h
- ]);
复制代码- 新! H, Q- i- m, c P* C" \( q& O1 ]
- $collection->updateOne(5 _8 y3 `; b! P( b2 u
- ['state' => 'ny'],
9 g; W. x% v; T( B" U4 f' _" y/ O - ['$set' => ['country' => 'us']]% H( J( K/ i$ U: R8 B
- );7 }$ o% ^( i1 z% C* t( j
- $updateResult = $collection->updateMany(2 p. [9 X3 M, P, L: f
- ['state' => 'ny'],
! u% H) d1 r6 y3 q - ['$set' => ['country' => 'us']]
8 b( F/ C! K6 p - );1 e) x: {. z: Z; Z4 {5 D. t
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
) o/ E, ?6 f! z. z& t5 }& x" u7 J
- $cursor = $collection->find($condition, [
/ v! D6 {6 u! s! [ - 'name' => true//指定字段
, r& x$ S' _4 P - ]);3 ]. Z) s+ ]; s- p/ B; f% w0 Z
- $cursor->skip(5);
, j! Q: I4 ?) I- X - $cursor->limit(5); Q# `8 h: E& x
- $cursor->sort([
, u+ S5 k1 M5 `5 f* j) b. P - 'time' => -1! B9 d; q, f: S$ w+ u0 u
- ]);
复制代码- 新
- G# c. r6 [; d" A+ K# M
- $cursor = $collection->find($condition, [
7 Z) }$ w( ^/ o3 X }! U - 'skip' => 5,8 z% R& D4 W* `/ V
- 'limit' => 5,
4 Z! X% n5 `& M# C - 'sort' => [
' S2 Z/ ]- t$ q2 }* j - 'time' => -1
5 e* u0 ~) R: O3 y4 `; O5 D4 P0 X( u - ],//排序/ H' _ e2 Q7 T1 N
- 'projection' => [7 T) a1 \- z9 ^0 i/ i. Q
- 'name' => 1//指定字段. a7 |+ `% S5 a9 `( j' q. t
- ]
' W/ I3 a1 v6 ^: o - ]);
复制代码 5.删除- $collention->remove($condition, [
6 X1 Q: p3 U+ X8 K7 i. u+ ^) f - 'justOne' => false//删单条
* F# P; Z. Z% h) j* l! ] - ]);
1 O" v/ ?9 C3 R9 { - $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);& S1 W2 e9 V+ z, H6 w1 x
- $collention->deleteMany($condition, $options);$ x8 L* Y; x' z9 T2 q
- ; J7 w2 n6 J6 w, B$ j9 C1 L- |& _
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([' `: @5 l' T& @, ^
- '_id' => $tableName//我在自增表中用其它的表名作主键
9 R/ ^% x L w& b, p2 b - ], [! Q9 d$ I7 X$ e7 `8 A
- '$inc' => ['id' => 1]//自增
& w0 k$ m% v3 }7 Z5 b; z$ [2 t/ v - ], [
J& [" o2 J: b! x$ i& L - '_id' => 0
# z& A3 h9 z1 ?; q. z' a - ], [
! S4 Q# f$ s, i- d7 @0 _1 @: J3 u; Y2 } - 'new' => 1//返回修改后的结果,默认是修改前的( I5 n% `1 B2 j- `: I
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([0 o4 q& t( ]4 P1 t
- '_id' => $tableName
- F/ d: |4 b& b2 h# h - ], [' P! ?, H4 M* P
- '$inc' => ['id' => 1]; Q, z; k2 \' l9 f' L
- ], [& n4 q: ]# b5 T+ L* K
- 'projection' => ['id' => 1],
, T- R8 J- j! P6 I4 G# u+ O9 d) S# c# R - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER$ _# J8 Q* i2 U& e5 z
- ]);
复制代码 o. x; B) ^" f0 d, Y3 T" f' U1 @
8 r$ A7 R( k3 ]) x: E
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |