|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php, C; \) F. v% C1 _- l
- , c8 {: C e& Z' I; Y6 j6 q
- use MongoDB\Driver\Manager;% T+ l) F/ H6 |6 y9 k& K
- use MongoDB\Driver\BulkWrite;8 @5 H$ ?+ Q, }9 M) `
- use MongoDB\Driver\WriteConcern;/ _6 g" Q3 C; `0 I
- use MongoDB\Driver\Query;
; S9 V$ R- l3 S. U; a - use MongoDB\Driver\Command;/ l `7 T% H) Z# m) N
- p/ o0 ~( t6 ?5 z5 ?) ?/ P/ M+ x. E$ S
- class MongoDb {
5 x$ G& ~3 X6 w9 f+ O. t
4 |" j) K5 k9 T6 p/ h- protected $mongodb;" ^5 n; p6 J9 u) j. T" h" r! H
- protected $database;
) C L1 E( `5 }' `9 ~ - protected $collection;5 k: f+ |/ J! H( d1 Q
- protected $bulk;! g1 g/ \3 x' l0 Y; Q7 ~' J
- protected $writeConcern;
1 b6 u- f; B* a6 u$ z - protected $defaultConfig
: K( a$ A$ T; ^6 [. i( ` - = [, M/ m9 ]% O `5 K3 t
- 'hostname' => 'localhost',, R# ?; `" K) w
- 'port' => '27017',) ]* H T8 |& k. j; h
- 'username' => '',( z1 e+ D `' {
- 'password' => '',
2 L- q) F5 @7 |' q0 K - 'database' => 'test'' \- i9 w5 L% N5 L3 a/ u
- ];5 I2 K8 N0 x& F' S+ g( [8 f
- 3 j# r \; p6 y. s2 _: B2 n
- public function __construct($config) {4 o3 d, m/ E+ S9 N/ o
- $config = array_merge($this->defaultConfig, $config);% h$ k% t! [' t: B9 U6 p
- $mongoServer = "mongodb://";
& D6 w! C7 O# L3 Q8 W7 h" \) H - if ($config['username']) {
( J3 X9 Y* `8 C1 w - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
. ~$ w) s9 p: M* Q2 r3 G( b( I, } - }
$ o$ l/ { w" H9 j - $mongoServer .= $config['hostname'];
( N2 N3 B- e0 U5 O2 l - if ($config['port']) {
3 ?; u2 d, L8 `" A - $mongoServer .= ':' . $config['port'];, }2 D6 E" w1 A1 k' g" o" v" d: M% C
- }
- e7 h1 c' m4 g8 j2 N - $mongoServer .= '/' . $config['database'];
( a$ T o2 \0 H" t2 i+ Y1 O/ M - - M/ P- _% O. U" ^2 e4 d
- $this->mongodb = new Manager($mongoServer);
; l6 C- ~% p1 v - $this->database = $config['database'];
5 g4 D5 m* H4 h+ _ - $this->collection = $config['collection'];
; M* k& z3 f0 ^ - $this->bulk = new BulkWrite();
5 \! A0 f q3 ]1 m - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);8 |- X) z& y3 Y2 o: ^
- }
: {( ^5 k$ p3 a+ R) c
4 v) s( K- X2 m i& n. L- public function query($where = [], $option = []) {
8 e; V% ^ B7 y9 | - $query = new Query($where, $option);0 T* r) n: r1 N) [. Z: M+ @0 Q
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
) t6 }7 j0 r1 K7 e5 `) _+ v
7 c% z0 d" V% T; O% p. h8 ]- return json_encode($result);
' l+ P* ]3 E5 n0 T, t( @7 z - }7 g1 ^4 Z. f* V
- 5 E5 x) N5 n: @7 L& `* O% ]/ d
- public function count($where = []) {
9 N- v+ W3 h g - $command = new Command(['count' => $this->collection, 'query' => $where]);1 x* | r% V- d6 M# ]! o+ `. M! l
- $result = $this->mongodb->executeCommand($this->database, $command);
: g; u" f/ J: a0 F - $res = $result->toArray();
# l' {- w+ [- i# e6 a, U - $count = 0;$ a- e$ x+ u: h1 c/ g5 Z6 `
- if ($res) {, F& L% ^8 N% l; T X7 u
- $count = $res[0]->n;
4 `' \: p9 I* X - }3 T! M$ d; M7 c; _- P! g$ z) F
- 2 @* k9 a# J; b/ E& ~
- return $count; d/ b; K( O* Y5 Y- L
- }5 D6 r2 Z9 Y* x# R( u, ^
: N. B' A4 D( i9 j" g8 u; D- public function update($where = [], $update = [], $upsert = false) { D& L6 v0 g! H6 k& x9 g( X
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]); T% i' T- r4 x: _0 P
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
& {' ^$ W6 [5 f
^1 o9 {/ }0 a7 y; v- return $result->getModifiedCount();
( v _: B+ j0 Q0 |1 K - }
5 Z. U# Z& t: M) E D - 0 t+ D. x0 M1 l U0 Z+ R+ o5 c& m& e& r
- public function insert($data = []) {& d; u" S' L7 t1 `5 Q
- $this->bulk->insert($data);- Q$ N/ [) M+ w4 F# y+ y% y
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
]3 R, }6 O9 [" p. ] - 9 @% Q8 y0 y6 b# g* \
- return $result->getInsertedCount();
0 l' K7 M; U! G - }
$ @6 `0 k2 c- P+ N$ q* l8 |
0 o% R* s: U- O$ g- i- public function delete($where = [], $limit = 1) {
' l" X2 m6 Q$ t3 k - $this->bulk->delete($where, ['limit' => $limit]);$ T/ h8 G7 x( s% ~' |- q9 k% `- Q
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
+ e& @2 g( R8 T) J" N0 p
# `9 o e, y9 v- return $result->getDeletedCount();
6 G, C; B, m T - }
8 N% _# P! J; E9 I T - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接2.新增- 原
0 [+ C, j. S6 M b( j+ H- L5 ^
- $collention->insert($array, $options);
复制代码- 新
# @! z2 P- ~* R" m9 P* f
- $resultOne = $collention->insertOne($array, $options);//单
g$ U2 k* U- x/ O - $lastId = $resultOne->getInsertedId();
$ u% o+ g- q/ J5 J4 S+ s - $resultMany = $collention->insertMany($array, $options);//多
1 j) G6 v; Z# z2 I - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
) P# ^: n. @7 q0 E# A( Z
- $collention->update($condition, [
) b+ f. X, S% U4 m; d - '$set' => $values9 x7 B4 [% J" Q9 Y/ h2 l2 z( z
- ,[
3 ?! z7 m" P' B6 U/ a - 'multiple' => true//多条,单条false5 z8 L# n& N4 i! w7 Z' {) u0 E
- ]);
复制代码- 新% X* J8 S. n1 I, d! v: d& `" V
- $collection->updateOne(
. k$ f0 v2 M0 ~) r c - ['state' => 'ny'],
M7 J, W2 Y7 W* T# ~ - ['$set' => ['country' => 'us']]
* |/ l7 q6 f1 g! u+ m5 [$ O& t - );
8 m. [2 i# P9 H0 ~ - $updateResult = $collection->updateMany(
} v/ L& q' }0 `9 v6 D7 L' H* I - ['state' => 'ny'],; Z) e. Q- M+ i9 z1 x5 V/ y
- ['$set' => ['country' => 'us']]
3 l+ \, `. e* D3 x; a - );
5 |% V! g4 E5 R6 M/ C& O/ v - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [. w9 Z, U" k! @# ^* n/ L
- 'name' => true//指定字段+ x4 H6 E' D6 z% I; w
- ]);7 n+ n+ A& y+ \* l. h. ]& r
- $cursor->skip(5);
$ b5 c! ~( D/ {+ m1 } - $cursor->limit(5);
7 G) \) E# R2 W) W. n1 u - $cursor->sort([
8 B9 H' V" u# L! v6 V - 'time' => -1
" }# s" [! s5 r5 v! N. L0 h - ]);
复制代码- 新0 Z5 `+ w' Q& S: j6 V8 R
- $cursor = $collection->find($condition, [
$ y7 {( l+ M4 H - 'skip' => 5,% l/ T# z+ E$ ]0 Z7 [8 g0 N$ Z
- 'limit' => 5,
' h( b% L* }0 n+ v( { - 'sort' => [
- k; W* a+ ?/ \8 H - 'time' => -1
! r; R, t( d) | - ],//排序
( ~2 i) J3 {! o1 @& M - 'projection' => [
2 x6 ~" s- x J/ p |4 i - 'name' => 1//指定字段
7 J( I# |0 e1 Q$ G4 K - ]1 k( T V$ T4 U2 B6 ^, k
- ]);
复制代码 5.删除- $collention->remove($condition, [
1 Z( y& |& z' U* j - 'justOne' => false//删单条 P" P; v6 n) B9 A) F& ]/ m8 I6 F
- ]);% A( i) j) ^8 }" v/ ?4 `
- $collention->remove([]);//删所有
复制代码- 新9 l4 R5 z- ?8 I1 S- s1 p2 X7 ?
- $result = $collention->deleteOne($condition, $options);( h$ }% I' v+ N. H6 Z
- $collention->deleteMany($condition, $options); F# U" W5 p+ A9 j; U# u. s1 G
% ^: ~9 S3 J! [5 e' {- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([/ q, B# n- Z7 ]
- '_id' => $tableName//我在自增表中用其它的表名作主键* n, g- T% [, S' q: K7 o: @
- ], [9 s& l' a7 a3 o, E
- '$inc' => ['id' => 1]//自增
7 v" R$ S$ \" |# p/ A* ?' h, }$ I - ], [% U8 d# ?- ^" s3 B( d
- '_id' => 05 C3 h4 X0 b8 C8 Q3 a% ]/ {! W& d
- ], [" S/ |; H$ P; u# \( _
- 'new' => 1//返回修改后的结果,默认是修改前的+ v0 R$ B6 R2 ?4 w
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([( n4 P& u7 p5 V& ` w3 p
- '_id' => $tableName
; f5 o. i; m# ^, O8 w. g - ], [- S7 X D2 k8 d+ s( g
- '$inc' => ['id' => 1]
- \) ~- M1 x* E( _* X! T - ], [
$ o" |( X: i0 ?( q j8 Y U - 'projection' => ['id' => 1],1 s1 C; C' K6 J
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
2 a" L0 H9 s3 D. w. p - ]);
复制代码
2 q$ p9 c- L) N
/ P* z1 n2 D. l% M) _, @ |