使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
" F; i% v! K# F- G - , B6 _# A t7 I5 i! `
- use MongoDB\Driver\Manager;3 \ A+ i* H! ] L8 P* o4 V! q
- use MongoDB\Driver\BulkWrite;
: t/ T, u& T2 ?" e - use MongoDB\Driver\WriteConcern;
) G* ]! O1 S" B% p; \ - use MongoDB\Driver\Query;
- h6 Y; d4 k7 X# ~; [/ g - use MongoDB\Driver\Command;& x3 d; w0 d* f" p* K' O
- . C% h/ f( f/ F! U' H. S) |
- class MongoDb {0 C# ^( A, f! ~0 _- M. R
) o2 G! I5 b$ V/ R1 g( l" V* x$ L- protected $mongodb;
8 H8 m, o& T z* J6 ~* B - protected $database;' n& U4 a) r8 H) o: v. _3 x1 }$ E4 g
- protected $collection;
h- Y' m* v. F% i5 F - protected $bulk;
. \0 M, n8 x- f( I$ T - protected $writeConcern;
* F |' F2 ^0 N& [& ]4 w3 E - protected $defaultConfig, g+ B. k. B5 Z
- = [1 b9 O; z% G7 P9 o% R3 M
- 'hostname' => 'localhost',, k2 ], k c/ |/ N
- 'port' => '27017',) V7 s4 z1 y( S# R- y; R8 H, l
- 'username' => '',
6 L" L% S0 S. B8 o+ m# z2 R) V - 'password' => '',
. m" Y. _% \: d* ?" s5 m/ h - 'database' => 'test'+ f! s# V+ F5 z1 G2 Q
- ];& {7 y1 v# Y( }% m7 K
8 k3 V f E; O- public function __construct($config) {
% }+ g$ x, J% q3 y+ _ - $config = array_merge($this->defaultConfig, $config);
3 n9 g7 d1 W% Q: `$ _ ~8 [# D( | - $mongoServer = "mongodb://";" Q) @* ]2 ^! N3 K+ O6 ~- X
- if ($config['username']) {
6 `: [. f* [" q9 o8 J - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
1 h l. O) V' n2 B5 b9 ], | - }
1 N& T4 N3 x. P1 R" s - $mongoServer .= $config['hostname'];5 h. t- D4 V! N) ], _3 C$ _; |
- if ($config['port']) {* P ~: q$ Z6 f
- $mongoServer .= ':' . $config['port'];' Y$ E* K/ X0 R( r
- }" l' f$ O+ p0 Q
- $mongoServer .= '/' . $config['database'];" K5 M9 K+ Y- |( W/ E! R" F; {
$ O6 B1 p! G J0 @9 {6 i- $this->mongodb = new Manager($mongoServer);6 v+ x( j. v( l; z* K; u& }
- $this->database = $config['database'];
& f) U+ c# M& m$ e8 F - $this->collection = $config['collection'];& I1 T H5 C) _2 q+ n
- $this->bulk = new BulkWrite();
5 Q' u3 g, y3 \8 o' N2 I - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);# G7 K9 a3 L$ ~& M
- }
) N, q1 c( _" Q. Z
- F! y( k7 M" T( b5 H1 j" V9 v- public function query($where = [], $option = []) {+ y. F" H& K6 [4 ^3 f$ |
- $query = new Query($where, $option);
, G4 i2 }; P" b8 M - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);7 C% d: x$ f; {! m# \) _9 H
- 4 k7 w% a4 u- w7 {- R1 V, x
- return json_encode($result);
7 g4 i6 |1 M* \ - }
- d5 r( _3 f# @# E% c3 ] - % R: Q- {: G6 m$ g: S3 o4 q/ z
- public function count($where = []) {
# n# X) a& `+ q% d6 c - $command = new Command(['count' => $this->collection, 'query' => $where]);
) |" N2 r5 _2 I6 v2 R0 k! ? - $result = $this->mongodb->executeCommand($this->database, $command);
# V, t6 }; V* y e7 [# ?$ o' E - $res = $result->toArray();+ J( n2 N* j0 B) D" P
- $count = 0;5 r7 l) y; Y; z
- if ($res) {
5 F6 _3 y4 ~5 [) e5 _* a - $count = $res[0]->n;. U5 l2 a; r' y' ?+ G. ?* D
- }4 Z" Y. X' L% _( V
7 B5 R1 f4 g2 N2 w3 F- return $count;& b4 r0 U M$ X1 p
- }
7 Z6 G' u5 L- L. a* N: c5 Q5 M+ K+ s& ? - - ~* k; ?$ L* [& _3 g
- public function update($where = [], $update = [], $upsert = false) {' K) I) C: x) a
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
/ q$ `" h! l: p! x& i8 F9 u, c - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
+ l& F4 n7 T1 L/ M) G) K$ o& f - # A: h* k. w# g- u4 C6 E9 Q8 j
- return $result->getModifiedCount();6 ^- ]7 e% m8 P
- }
) e3 g6 J! s2 l# C0 P
+ U- ?. P4 D- J$ S; ~- public function insert($data = []) {
8 S$ c1 x L+ K: b$ \( L1 z - $this->bulk->insert($data);
Y8 T D6 y3 ^8 p, y( R0 l# }" P - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
0 y, {7 t7 U b' B' h& o - % G2 e {$ i# E. j! z
- return $result->getInsertedCount();
! [8 A* {) O1 R/ C7 Y6 S+ G - }
' _- p" h. [( w( K8 ^( v
4 r6 X0 X d G) S. {- public function delete($where = [], $limit = 1) {
( m* k, y; F% P# t' d* I - $this->bulk->delete($where, ['limit' => $limit]);
- I u6 I1 r1 q# |" V - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);7 H+ e0 W1 \! w* G+ J$ x
p0 U5 {+ w/ u! ]# G% K- return $result->getDeletedCount();7 o" A% d o* N, D! ^
- }/ t5 t( `5 d. v1 R; V5 z
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原
( d# T5 t: [% P' ~4 _5 Z
- 新; J6 \9 N9 {5 z( w8 T, u
2.新增- 原3 T- N2 A4 h# [( l" e* g. o
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
2 K. t% c: i* I2 ?! M2 _ - $lastId = $resultOne->getInsertedId();) t% p& F* R! R& c0 {3 I0 ?+ O
- $resultMany = $collention->insertMany($array, $options);//多9 B0 ^( E/ t3 ^' ?- N6 \7 l( {
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原: i7 r! G7 n0 i6 F+ f( k! j0 h
- $collention->update($condition, [
+ r/ g: i; ~/ o& F - '$set' => $values
% r) K2 K/ i2 v4 N& |0 p0 e - ,[
9 e8 i! f" D; h' s, t2 V% B& Z - 'multiple' => true//多条,单条false, F- V6 w! L2 Z; T* N
- ]);
复制代码- 新
1 ~0 b/ A! Z O/ C- a1 g
- $collection->updateOne(9 a, Y6 [6 u6 x, p
- ['state' => 'ny'],5 g3 I- b) p, W3 p2 N+ c' T. E
- ['$set' => ['country' => 'us']]
. c. e5 d2 z; R# [0 | - );& L/ J' J4 m+ I) W8 L p" d6 o$ o
- $updateResult = $collection->updateMany(5 N8 n0 S# ?. @
- ['state' => 'ny'],, j) y g: x, f! k' s1 m
- ['$set' => ['country' => 'us']]+ Y: X8 e6 ~ ]0 r4 n
- );* B! {3 k9 k2 G. u
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原# A6 Y" h; x8 l, t$ U, X
- $cursor = $collection->find($condition, [
8 n, ]# V2 D/ t# W" `% k - 'name' => true//指定字段
" @3 \* p* L+ x) J. t1 ^ - ]);/ s1 [3 h, h, g" |$ R2 S6 o3 [
- $cursor->skip(5);
! E* e. v% w! S) _5 x3 i) z' j - $cursor->limit(5);; z! {+ n( A, w+ `# E: V$ g4 c
- $cursor->sort([7 I+ o! X+ U( V" I8 i
- 'time' => -19 ~* `9 Z/ J# T# _3 p, T
- ]);
复制代码- $cursor = $collection->find($condition, [
! f) z/ D" d0 h0 E - 'skip' => 5, V) X& L# j8 ^, L! S% [
- 'limit' => 5,# b/ T4 V5 S/ H
- 'sort' => [$ a7 Z: w& K3 ?$ S- ^
- 'time' => -10 Z2 t( c1 f' Q8 ^, z, d
- ],//排序
w+ A5 o3 u- j - 'projection' => [- W9 M* Q0 A b' e
- 'name' => 1//指定字段) p# B% P" u7 R
- ]! H1 @' T4 i) i' {: O" h
- ]);
复制代码 5.删除- 原; L: Z3 H& U# z# F3 r3 v! d2 @
- $collention->remove($condition, [
/ C1 T0 r. h: p! _* O0 \ - 'justOne' => false//删单条7 x& N/ Z3 F! z* Q: m
- ]);; F3 L& M7 P7 S" a/ y
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);, C O% F! V B+ g
- $collention->deleteMany($condition, $options);0 y* ]* d5 e2 b: ]3 c
?; b g( B: H! `- f- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([! C% h: e" S( [' x) f
- '_id' => $tableName//我在自增表中用其它的表名作主键; R4 R, l, J& X% H: S" Y1 F$ Q
- ], [
, q5 y! ~, R$ S/ U& g - '$inc' => ['id' => 1]//自增
R/ o2 x B, \6 v& I$ e2 W - ], [
# {8 T. w R, S; t8 i+ y& L9 H - '_id' => 06 L, \1 e. n% h; R
- ], [$ o0 |- b- Q4 c* u- l/ m
- 'new' => 1//返回修改后的结果,默认是修改前的
% V! N0 _# y5 q2 b/ p7 H [ - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([' l# N; r, x0 T& `" f
- '_id' => $tableName
k3 p4 M! e4 v6 Z - ], [
* o5 J. h7 j8 Q* G1 v. p# ^ - '$inc' => ['id' => 1]& l! P- `" k" e8 u e! O v
- ], [
4 ?1 ~. T' {$ B) t. @, j$ l - 'projection' => ['id' => 1],! q% D B0 k$ P% v! ?
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
- e- s8 O7 D+ n7 G4 R7 I- W* ? - ]);
复制代码
# r% [8 V5 u- w; r) ]) `9 v" k2 @% ]4 _8 x! P+ m
|