使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php" L. j$ @/ U6 j+ X- ?. E/ [
D- b. B6 b* T- use MongoDB\Driver\Manager;2 |! G3 {- U: y0 [. x% ]
- use MongoDB\Driver\BulkWrite;
$ n1 ?$ j% Z, K X% M: @# Z - use MongoDB\Driver\WriteConcern;
5 _: \/ M7 H7 h8 n9 \ - use MongoDB\Driver\Query;1 Y; W/ }* f* o. x' H
- use MongoDB\Driver\Command;+ X6 |) U4 W b& N9 J
- # x3 V1 Z! d6 m6 e) _! N
- class MongoDb {
; A% m1 V, K1 ]8 f1 q( |2 u$ ]
$ L8 k7 n7 r2 D& J- e- protected $mongodb;6 ~0 i3 Z& l# g6 U, z: c0 B$ Y( v/ _
- protected $database;8 g! X& i% l# }. p; R: W
- protected $collection;
, i( [' b; R, E/ ^0 F$ t - protected $bulk;
; W2 k- a( l3 U7 q - protected $writeConcern;5 A5 w# d7 m/ D
- protected $defaultConfig+ M1 B" u- {: A: S& Y% |
- = [, L: H3 b0 d; ^; p1 q
- 'hostname' => 'localhost',7 _7 A' X9 u( b8 M- @5 U, Y
- 'port' => '27017',7 z# M& ^. U h. a$ \( e4 {
- 'username' => '',
. Q; [: N0 Y; Z& ` - 'password' => '',
9 P. L5 f& K3 T$ R' M( B/ | - 'database' => 'test'
1 B+ J7 u0 ]& I, T# M; m! O - ];
8 G! d: l9 q3 X/ @. ` - # E) A) I& i n# ~
- public function __construct($config) {
3 w- Y+ J6 L+ S# @" v - $config = array_merge($this->defaultConfig, $config);
; W" s3 ]0 E; @0 m. q - $mongoServer = "mongodb://";
+ c z H& S R+ E4 U - if ($config['username']) {
" ~' `: N& W: r. k, K - $mongoServer .= $config['username'] . ':' . $config['password'] . '@'; U! |) m3 @9 I/ w8 }9 L4 g
- }$ O# F) h* n& N7 C
- $mongoServer .= $config['hostname'];+ y" I, i4 ?- ?( I* `
- if ($config['port']) {
. W; E6 y( {; d8 s2 L' g7 r - $mongoServer .= ':' . $config['port'];
% o4 L' m4 f* b - }
3 }9 D" V9 U, I - $mongoServer .= '/' . $config['database'];
% K. T& x) W; M+ z - , ?+ i6 `3 Q* a2 z# \
- $this->mongodb = new Manager($mongoServer);: e& W6 ~6 s' y( t# r8 ~9 A5 P
- $this->database = $config['database'];
. s% B- t: v# X( d - $this->collection = $config['collection'];
+ ?% o$ Q: T4 O' x5 {$ T' k - $this->bulk = new BulkWrite();2 g ^# H6 W( q
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
% t: Q8 Y1 c& G - }
" |# @, u8 d' F1 w) j
) u- {) f( H3 L+ d" S- public function query($where = [], $option = []) {4 P# F+ q1 |( ?' L1 t( H; g8 ~
- $query = new Query($where, $option);9 r4 I/ w4 c2 E+ r& |5 t8 Y! b
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
2 [0 K; [- d2 y! s4 T% I: H - ' H4 q `: e* ?
- return json_encode($result);8 o( F+ g& F6 g; M. E7 R
- }$ X$ f+ {' g% _1 i8 n1 M
+ }. H+ Z R0 Q: {6 C% ]! c+ S$ a- public function count($where = []) {1 N, o) s& Y+ [, F4 F7 G
- $command = new Command(['count' => $this->collection, 'query' => $where]);: d+ q7 d( l$ D6 y4 z' ^
- $result = $this->mongodb->executeCommand($this->database, $command);" G3 \. h/ J' M8 ^" x3 ?1 k: p
- $res = $result->toArray();2 F7 o, g1 [ `/ t) N/ V
- $count = 0;
1 N- _2 E+ k7 E! Z - if ($res) {: z0 K. R7 {- M4 t0 K
- $count = $res[0]->n;' Q7 E/ |5 [- _2 G
- }" d! V$ p; y. n' m. G, i' \
( R7 _3 D6 T! L% S4 q- return $count;7 K f3 o3 ?/ N
- }/ B( P7 V9 F! z' L
- {6 c. e& G' }4 a, \; K( ?# f8 _. \- public function update($where = [], $update = [], $upsert = false) {! O# ~% `$ |* |0 h( C
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);( k! G2 t6 w G. ^7 O! ^. X A
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);5 c$ O ~ `6 G$ z: L! P
" \. t: u/ E* ]3 W/ _- T! o- return $result->getModifiedCount();
5 L; h4 i* l5 ]- G/ u1 I - }
, q, ]/ }% `" h3 U - 6 I# Q8 S! a" |+ @" ~- T) w
- public function insert($data = []) {
( | D. H- s7 B, Q7 F( e. ]- w - $this->bulk->insert($data);
& N5 B/ d% l+ y/ x - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);$ t5 m; S3 c5 T# | r0 g0 ?8 x
- % d( }9 w ~: F: P% M! |
- return $result->getInsertedCount();
4 B3 O) r) F5 S3 E3 L+ ~) e8 {0 ` - }1 D1 D/ O& X3 @& ]% Q J
4 K$ c- ~, i2 s- ^- public function delete($where = [], $limit = 1) {" A5 o" Q/ J& W4 H4 w2 _
- $this->bulk->delete($where, ['limit' => $limit]);
+ G+ g I& y, G+ G3 O Y - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);- O/ J5 H9 s. ]) L2 o4 J
9 l; G# F0 v2 r3 \1 {- return $result->getDeletedCount();
1 A; h, [1 b& U( u, l* f - }; d& D3 H; M8 \
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接2.新增- 原% X5 V$ p- y. I! P' R" N! W
- $collention->insert($array, $options);
复制代码- 新
: r- J! O- \ X" Y r8 M# I
- $resultOne = $collention->insertOne($array, $options);//单5 ~% Y- D7 ]7 L; ]6 |3 J* g" n3 C9 V% j
- $lastId = $resultOne->getInsertedId();3 h( R0 K( Q u3 z* D
- $resultMany = $collention->insertMany($array, $options);//多, t; H% Y3 Q/ C. }
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [
2 |: G5 p F( r6 z" \' [ - '$set' => $values
" w1 G: E [. U# D/ d) Y. g - ,[
6 k6 V/ m; t4 c) V5 w0 _ - 'multiple' => true//多条,单条false$ a' w& E- b: M2 o% u2 K3 b ]* D
- ]);
复制代码- 新
! c, ^6 I/ P8 o8 I$ B+ x( E
- $collection->updateOne(
; Q0 K8 j* D# K. e - ['state' => 'ny'],
* p( y% c3 n6 U% c- R - ['$set' => ['country' => 'us']]4 p/ s+ s. Z9 d% X# ?4 z2 a
- );/ S" u! A2 z# I; g
- $updateResult = $collection->updateMany(
+ {1 s% _- ^3 I# v$ F7 I - ['state' => 'ny'],
+ x9 R* a+ c8 ~8 w0 @ - ['$set' => ['country' => 'us']]
" H& X& W' G, N4 ]6 h" `! s* L7 j - );. s, f7 f7 m O2 h5 l/ C0 i
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
# t; ^" I, J" A6 x( {7 ~' d# d
- $cursor = $collection->find($condition, [& W: N1 e7 j! L7 w& X" w
- 'name' => true//指定字段) S- q2 c: F* S: ~7 T0 p
- ]);- q! t y5 |9 ?
- $cursor->skip(5);
& J; Q9 w4 U# q1 U6 w$ @ - $cursor->limit(5);: k/ Z. Y' P7 ?& I2 G
- $cursor->sort([$ o& d) Q, `9 J
- 'time' => -1
& M; ^! r. c/ G8 t: ~ - ]);
复制代码- $cursor = $collection->find($condition, [
+ y/ v( G* S3 ]# R5 g# }# v - 'skip' => 5,- `+ _& I! U! c; t
- 'limit' => 5,# P& `1 P: y; x
- 'sort' => [
3 u3 ]6 n2 w* v$ N+ N0 T - 'time' => -1
+ X3 ^& t P' z0 i* k- w- S - ],//排序* J |$ V( c) h' x9 H) G! ~
- 'projection' => [
5 F( Y' T. A- p1 l- U' e; _9 R' y* T( x - 'name' => 1//指定字段* g* m4 f& y. E K& \
- ]
- s9 m& B$ [, Y% u1 T) _, O - ]);
复制代码 5.删除- $collention->remove($condition, [
A5 t. S* T; m9 N' c# T - 'justOne' => false//删单条8 R' s$ g9 T! M) K3 S; k- ]
- ]);
& e1 i7 d3 q0 H - $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
+ z! Y5 s" ^1 |. K5 Q - $collention->deleteMany($condition, $options);
$ v8 I; p4 {: R) |, h) b( K7 G - $ F* J1 N* @+ L
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([, v4 b& l2 u9 C6 S
- '_id' => $tableName//我在自增表中用其它的表名作主键5 m0 B# q, d2 T# |1 H5 ^3 a' s/ A
- ], [
" I6 |4 n, V. Q6 \6 n5 _. M" H - '$inc' => ['id' => 1]//自增' z6 f4 j6 I6 x* [: e
- ], [/ [# c* X+ r% G) V9 P7 b
- '_id' => 0
: z# L) v7 }2 L7 c; w1 b* X' k - ], [
* \* }. m* f0 I6 H - 'new' => 1//返回修改后的结果,默认是修改前的
0 X0 [ G b. `* T1 K2 @& R/ Z' }! Q - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
+ d% G6 P2 b* ]! m' d - '_id' => $tableName9 s: P! L( b$ O7 B
- ], [
1 s1 F) w$ z8 l" i: w) u - '$inc' => ['id' => 1]
- ~1 t, e/ ^# B. _. h - ], [
4 x! l+ T4 G r - 'projection' => ['id' => 1],
) g+ P4 f* u2 p/ r) Y; _ \ - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER6 Y2 V: W9 ]3 q
- ]);
复制代码 2 O/ M/ t& T! R+ a! R6 I' u
2 M. h+ Q5 T. w9 e4 c
|