|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php' ] K1 F3 M! K$ `! t3 ?
. w; m3 h9 N$ M4 S" N7 J- use MongoDB\Driver\Manager;6 s/ X* J' f! y
- use MongoDB\Driver\BulkWrite;' v+ x: a" T1 z. J# M$ i5 Q
- use MongoDB\Driver\WriteConcern;$ o: a/ T9 E: [* y# Q& g4 {
- use MongoDB\Driver\Query;7 D$ S5 `' G( d% @
- use MongoDB\Driver\Command;
1 n# F$ G* T. \8 r - 0 `9 j) {5 W: [. S* f# D! i
- class MongoDb {* I6 }* ~8 I$ r
- % D |7 Z" X4 n5 m2 Z0 D
- protected $mongodb;1 F9 C, K. T) h9 B: O! R* Q' {
- protected $database;6 {- v2 F# u+ G
- protected $collection;
5 A/ g7 D$ i( P - protected $bulk;' X4 x. {) g5 A. T9 p$ d
- protected $writeConcern;
: e# |3 n; X8 l3 y3 f - protected $defaultConfig
9 X: ~; _8 p8 i/ M - = [
& b9 r& I/ F1 S& S/ [) Y2 { - 'hostname' => 'localhost',
# x, T$ K0 G. ~1 n& s - 'port' => '27017',
, w+ {; r" c4 {/ m9 u% p - 'username' => '',* U4 a& }( Y* [ ~5 P7 F
- 'password' => '',) q0 E% k& @. R2 Z4 E0 y: h
- 'database' => 'test'8 o$ X& w6 b7 s6 Z7 m* T @
- ];
) s3 |$ [6 J# ]6 z
, P$ g m3 H+ D1 T2 b- public function __construct($config) {
; p& e0 T& D: n2 b7 r - $config = array_merge($this->defaultConfig, $config);
- Q# Z1 _' ]9 |0 u - $mongoServer = "mongodb://";; |* [$ U! C. `9 \& y
- if ($config['username']) {- O- y# l* `: y
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';0 _) Q+ z; J. S( [( ^
- }: z: ?8 t' ^- o
- $mongoServer .= $config['hostname'];
Q! G% N; ~; j4 ^1 T3 b/ F - if ($config['port']) {
; |# Y. E* `* D' ~: V4 K' G - $mongoServer .= ':' . $config['port'];, ]' {0 g n {( Y8 @
- }
* }0 k- X& ], H% h: ]( Q0 E( h - $mongoServer .= '/' . $config['database'];
. v: F7 i' _7 F - 6 I! s8 v2 E6 X
- $this->mongodb = new Manager($mongoServer);& _+ s7 ^; H0 k5 r' _3 w
- $this->database = $config['database'];
+ A1 H: } v1 s) o7 V2 f3 J - $this->collection = $config['collection'];
7 i' x9 G2 O/ j$ L) ~5 D - $this->bulk = new BulkWrite();
. `/ L) y" m3 e% m6 C- P0 A& g - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
i" n3 Q! e( `( O( k - }
2 i. G9 P' k5 J3 K! X% e- k5 W0 ~6 b9 P - . g0 | o" q5 x$ A- D/ C1 D, ~
- public function query($where = [], $option = []) {8 r# g1 {) O* R$ l0 O: N- S, @7 M
- $query = new Query($where, $option);0 }( x* p5 {5 q" o3 ]" P
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);. D2 ]7 D9 T4 n- Q
- # C, Q- I B3 T8 m, d
- return json_encode($result);6 n& L. H, E# ]# S7 S
- }* B) G9 T# f' ?6 y7 h
) p3 O, D% V0 R! R8 Q. C1 Z/ c- public function count($where = []) {9 \+ C5 a5 a% r+ [! o) \$ [
- $command = new Command(['count' => $this->collection, 'query' => $where]);8 f. |; g ^* V$ ]$ T
- $result = $this->mongodb->executeCommand($this->database, $command);
; W8 Y% r7 K( m; z% i2 N) w - $res = $result->toArray();
" A4 {4 G5 e9 m) H; c0 ] - $count = 0;2 s3 W" b: z0 K. r8 O! c
- if ($res) {
) c) G9 S: B7 B3 n& V" ~+ l- x - $count = $res[0]->n;
& e6 y1 ^& J- ^" n9 h - }" b7 f* p G2 b J4 L5 {( ]
, d0 c1 H" B7 @2 G- return $count;
$ I2 N6 h# ^: T) z3 Q - }8 ]" d' u, N) P0 z) D9 r
# @ L2 [7 t; o g6 O' W- public function update($where = [], $update = [], $upsert = false) {
/ V" t# ^$ e6 g1 o" J- W) I - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);# P/ {* [, f+ \6 s
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
: t1 J% n! Q) F! r# `5 \
' w' R( [% F" ]. J8 Z1 [- return $result->getModifiedCount();% \0 R7 F' F7 [
- }
- W+ j; u% S+ ^: p$ W& v; k
! W6 ~3 A) @1 g$ m, n- public function insert($data = []) {. j1 ~. ]/ c: {" X u1 R/ y& N
- $this->bulk->insert($data);$ s+ [6 B3 G0 x9 _! W; t0 @
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
2 @1 Y7 j$ D& U s; y% K# p/ s - & Z; U1 x$ y+ ?" l& q+ e- {
- return $result->getInsertedCount();
- }! e9 L K" |. i. J: S - }
2 B3 \6 ~" G# x" J8 Q( O
9 J9 s& @2 e! ]3 B- public function delete($where = [], $limit = 1) {1 i7 L2 J* q, Y
- $this->bulk->delete($where, ['limit' => $limit]);* C% m `8 ?% a: G2 b3 J' S7 n
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);: y& `7 T7 Z" P4 e( V2 p
- ; B# I4 ^/ z! j6 g
- return $result->getDeletedCount();
# L! y5 @' }1 G! J) ]6 g - }
' v1 n& D' a2 S: c) t) B3 ^/ f - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 新2 `7 _& ~0 o( J/ M' k* Y* s
2.新增- 原
5 T1 D" d. w- s, i) z" G0 m% }
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
% f8 E( t/ c- X) I% z - $lastId = $resultOne->getInsertedId();3 L' r% g. ?% L: y9 @7 L9 C
- $resultMany = $collention->insertMany($array, $options);//多
/ P P; B; n& W- c j, z: V - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
, _ w' N/ h- l7 x- z% R6 Q" @" ]
- $collention->update($condition, [) o5 \7 G! F0 ^% P
- '$set' => $values( S; J* ~& Q6 [4 i
- ,[! G9 v) T. v! E4 O$ {
- 'multiple' => true//多条,单条false
9 {4 x, J& v5 j9 A7 d, N9 v - ]);
复制代码- $collection->updateOne(' z% G( ^3 _; g: ?6 ^/ g
- ['state' => 'ny'],5 q) ?( i4 t+ O; v
- ['$set' => ['country' => 'us']]
Z. U+ c& O' g9 I: m/ ?" { d: o - );
/ c4 T! Z& a H: c# I - $updateResult = $collection->updateMany(
( M' P: e. ]& M5 s - ['state' => 'ny'],: t9 n- L+ c( {( c2 k
- ['$set' => ['country' => 'us']]& Y; P5 n8 L0 d; u1 ]' o/ o
- );8 Q, x1 ]/ ]+ w7 Z
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [' ?+ o; k) K% u+ v+ c2 L
- 'name' => true//指定字段
6 R- {6 i b* x! @# O - ]);
3 @, h3 e$ L6 k: H - $cursor->skip(5);
! c9 `; d$ {# m) k# `1 G# ^: A - $cursor->limit(5);0 Q: f# a2 [2 i. O, d- @
- $cursor->sort([0 m! z; o1 f4 B3 R8 `# J3 M- j, s
- 'time' => -1" ]- d: Z0 S/ j9 a3 s( J
- ]);
复制代码- 新
; Y5 Q L! L* b7 S z# ^: D
- $cursor = $collection->find($condition, [
& d% s# m2 d+ j* B( g" H - 'skip' => 5,
( a$ {0 F6 F5 t0 d - 'limit' => 5,
8 O3 Y6 C7 A+ M; \3 F" o+ ~; K - 'sort' => [
6 p7 O: }& n% u8 w; z7 j7 X - 'time' => -1
) P! o: a' ]4 v# O7 M - ],//排序
( r8 y; S8 P J1 r" t2 \- K - 'projection' => [
$ k. e+ P, ]6 C7 R/ t) X - 'name' => 1//指定字段/ h, ?% i7 b7 V2 F$ m
- ]
, d# ?4 z- m; X) J& Y4 ?0 q$ M; {, H - ]);
复制代码 5.删除- 原
$ O! J# k* S. W- |0 S5 E( B9 n
- $collention->remove($condition, [
! u' M1 V) q1 D" ]8 `) q - 'justOne' => false//删单条2 [+ ?% w3 A, [# o- q% A$ J: [/ [/ l
- ]);6 P8 j z2 J. D- L
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
6 l$ |; d6 T3 ?: @) T - $collention->deleteMany($condition, $options);
) A! ]' l6 V" g2 \3 C
$ R3 A& f8 o/ t7 i( j- ^- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([. L3 D" X* `7 G
- '_id' => $tableName//我在自增表中用其它的表名作主键4 o1 z y, T" h" B( E
- ], [% J% s: @# m# ^9 v
- '$inc' => ['id' => 1]//自增
4 z [7 ^( u, x5 Y4 u9 H3 R - ], [
8 W4 X- }- C+ l( y+ R- p. } - '_id' => 09 k8 U" p r7 Y7 b, V* W4 k* t: c
- ], [
+ A- U4 d2 w. @ - 'new' => 1//返回修改后的结果,默认是修改前的) b) x9 K) C! P) n* v; z7 _3 ?5 r
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
, o5 Q2 ?- h" b2 y/ o4 y - '_id' => $tableName$ s% O. o7 m2 ^; V; l
- ], [/ G8 g: r7 r2 \( s+ H, O
- '$inc' => ['id' => 1]
4 A# d& e i3 c" R - ], [
" ?& }! v1 Y; S9 |# Q3 c/ X - 'projection' => ['id' => 1],1 m4 {6 v4 M4 M8 f0 ]( e* C
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER# m/ X# O/ F: T! _) i% e; c1 z C
- ]);
复制代码 & b0 ^& z9 y: Q* ~* Y; R
4 _4 N( c9 l& q M |