|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
0 K e N, G% v
) ]0 W9 p" O* e6 y: x+ d! x5 q2 d- use MongoDB\Driver\Manager;
8 O! l' x" f* s4 S% M& X - use MongoDB\Driver\BulkWrite;6 d7 U+ `0 a; {$ R/ r/ k
- use MongoDB\Driver\WriteConcern;
( j( k6 U) r8 E - use MongoDB\Driver\Query;
( o$ n6 J1 d$ _) B - use MongoDB\Driver\Command;
7 J, i( |# S! T+ r7 p. }; h3 T3 o% X
" U6 T/ a6 `4 {& f9 B |: u- class MongoDb {
) w5 k t% K5 ]4 W- A - : ~2 F4 J' \1 @6 H8 ?: V4 |; H! A
- protected $mongodb;
5 n6 X: k+ l# x - protected $database;
) F) R8 _- `$ p1 X1 @ - protected $collection; o( w, K% d) R# v- S: E
- protected $bulk;
( z$ s) i8 F9 V7 C, ]- a- x0 H - protected $writeConcern;/ t( E6 e0 m* q! R) \# A5 K, z g: |
- protected $defaultConfig
( H7 \4 o! D9 B' x - = [: A2 U: F/ e3 q5 K# D. y; Y7 k
- 'hostname' => 'localhost',& N( k9 e7 ~9 U+ h
- 'port' => '27017',
2 C9 Y6 j+ C$ o2 `2 b) D - 'username' => '',+ w, c: {' B- t
- 'password' => '',
' p- I' v6 G* m8 ^# n - 'database' => 'test'
1 d1 c( L& q: A* O/ @2 z - ];; I% Z0 Y S* x2 x, S- R
- 8 y, u: @$ M7 e* m% W# K
- public function __construct($config) {
6 e8 `0 \. ^: J0 u. s8 l+ Y# ] - $config = array_merge($this->defaultConfig, $config);
, J- [( n# V/ \3 _, v7 Z+ L - $mongoServer = "mongodb://";# U6 B* J/ w" E5 `, n, o
- if ($config['username']) {6 C( z2 B) z" p
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';/ }9 |! O1 F# Y; V
- }
2 L0 b2 K' W X& u, R - $mongoServer .= $config['hostname'];
1 H! R, E: C' j1 o0 I9 ?( B+ k - if ($config['port']) {1 J0 X! v. I1 O' ^1 }
- $mongoServer .= ':' . $config['port'];# M2 k! _6 A1 J3 y8 |
- }% k& h1 P- a" S% [( l3 l) u' ^
- $mongoServer .= '/' . $config['database'];' ?5 `: C* Q5 W. C& H" {7 @& I
- - j; U' I4 R, A% Q0 A* N7 ^/ h( D, S6 c
- $this->mongodb = new Manager($mongoServer);% ?! c- A# O) E2 A6 R7 t
- $this->database = $config['database'];3 N: ]: Z4 s- f
- $this->collection = $config['collection'];
; e: l6 t6 N- _) v0 g6 Y/ B - $this->bulk = new BulkWrite();+ Z7 }3 M) b& x9 E. u9 p
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);" Y( C( }8 _# k6 n: Q7 A+ d8 }* e. `: r0 L
- }; U8 n2 c3 w# E- i
- : X" E0 S2 F% t7 _1 j
- public function query($where = [], $option = []) {1 w2 H/ x m4 |! u1 ~
- $query = new Query($where, $option);) C. ?8 V+ y# f; m
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
8 F8 }( N$ P I9 A2 H
4 U# o+ E8 p* A) Z& ]2 v- return json_encode($result);
# ^ Y% B7 L; x! ]8 I$ \# F - }
/ \5 y$ A0 u% g0 t" |" K" ?
8 O3 V" B; z+ f4 s3 J N2 o1 O- public function count($where = []) {
$ C) o' w1 B a* o# {9 C - $command = new Command(['count' => $this->collection, 'query' => $where]);
% G" v# p* s6 F - $result = $this->mongodb->executeCommand($this->database, $command);
! e1 d: m, p( C - $res = $result->toArray();9 _1 f. z" p! m: J3 e4 ]
- $count = 0;/ U! o( s) X/ r0 @- n( w8 U2 S5 O" c
- if ($res) {
6 I- m2 u# P& b7 f `3 v$ L - $count = $res[0]->n;
8 @/ \; e: A9 Q5 A* Q# G3 ]* ^ - }
# d. k; K7 {/ v3 e3 R: E. I% |
5 k$ Z" b. `" _3 J1 L. R9 I- return $count;" |7 T9 b6 g$ \0 }2 d& k% Q* {
- }, A! h1 n. O/ v `+ ?/ R
- 4 j+ M9 _7 V6 p6 e) \: R
- public function update($where = [], $update = [], $upsert = false) {7 S( z& }7 I6 l) P. }( L4 O
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
) f6 [& ^3 T0 K6 H7 u7 H( k$ g - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
6 x# [ C. o3 L4 h/ Z) S - 2 o" q, X# y8 T" t5 R; e
- return $result->getModifiedCount();
/ x4 E/ G. @9 b) b, {/ \# q - }
i; W4 ?. r0 g, ~: }6 H - 7 @+ I+ W5 [2 i& }1 g4 H( P6 y) m
- public function insert($data = []) {
1 k' c% ^* h6 j6 ~) c - $this->bulk->insert($data);5 H/ y* ?+ M. d) e2 {
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
8 ~9 L" l. A- C- s
; d9 ~# N, O0 n- h7 n- return $result->getInsertedCount();- e: U4 l L% C
- }
7 O6 j& S8 F& j6 W
/ u4 p: r+ K+ s1 J* C6 o- b1 l- public function delete($where = [], $limit = 1) {. Z6 i; p' K" d; O
- $this->bulk->delete($where, ['limit' => $limit]);
6 K& E' ~; K( u9 G5 l ^' x - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
1 c, X) S/ N2 [# m. G: p9 P- ]
2 [* F1 ]: G) T% s5 u( @4 S/ g- return $result->getDeletedCount();) [- M. T( p% O! ^
- }8 k6 I1 z8 k$ j9 |/ y' x, h2 L
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原7 L( ]1 Q( m" p9 i3 D' m
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
% I& m$ U/ {4 V6 g3 Z - $lastId = $resultOne->getInsertedId();
2 ?; ]- Y$ c7 R8 [0 P6 \/ g - $resultMany = $collention->insertMany($array, $options);//多
% K+ C+ D4 z9 b& V# A5 j - $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [1 h, F+ g/ ^! e' i. i$ u
- '$set' => $values
# x+ x, }; e7 u" L4 ]$ |$ v2 j - ,[8 w7 I) J3 M6 h% Z' F
- 'multiple' => true//多条,单条false4 h C% s) b( f/ j/ y( a) r
- ]);
复制代码- $collection->updateOne(6 W6 |) _2 A o" ^2 ?. f: o; x
- ['state' => 'ny'],8 @9 B7 T- M1 C1 {- ^0 _2 {
- ['$set' => ['country' => 'us']]
! \8 O8 @, k0 C9 @% P4 z8 C3 n - );( J: I! r% o3 q" c* p8 C( w# E
- $updateResult = $collection->updateMany(3 P8 x0 @6 z. P* S& B
- ['state' => 'ny'],
1 {# ]8 e0 ], G) c8 W, x - ['$set' => ['country' => 'us']]' G7 E, A K2 S; k V
- );
' c, i# x! P/ d0 v1 W/ Z - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
1 c+ i9 ?* x% y9 X1 f( b - 'name' => true//指定字段
* B/ T" |( d; ]) X6 A1 x - ]);) C7 D1 T% [3 Q7 F; D# m0 m/ e
- $cursor->skip(5);
7 O6 d5 Q7 S7 A6 S! b - $cursor->limit(5);
* X3 k) ^7 e* o/ }7 S - $cursor->sort([' {& e. Y6 M8 Z% B
- 'time' => -1
) x; t! d- j, }$ e, Y }$ Q8 E - ]);
复制代码- 新! z7 b- x& a6 z) r7 f9 M, e6 S3 F
- $cursor = $collection->find($condition, [
9 l1 N* `& G$ k6 j) J - 'skip' => 5,. J, F& a+ s% l! p4 x$ W `
- 'limit' => 5,
) }( I3 ~1 I+ b: C - 'sort' => [; |. o% k2 y: v2 Q
- 'time' => -1
2 K( \1 X9 B+ m+ y' T - ],//排序/ S/ g* M8 J. `2 j% X: j
- 'projection' => [; z7 r! O$ _" v3 |- n9 L
- 'name' => 1//指定字段* y; G7 G" l9 V$ q2 t
- ]
& R. ^% s# j. J; m) U - ]);
复制代码 5.删除- 原9 i! g0 u3 ~# `& a( |) R N
- $collention->remove($condition, [* A8 D( r# f6 {
- 'justOne' => false//删单条
/ _: F4 H7 I- }6 ~. s9 O7 p0 K3 G0 z - ]); _3 f# q7 h) J' [/ V+ P9 ~! N3 [
- $collention->remove([]);//删所有
复制代码- 新8 n& J* i, g3 c/ ~1 k' Q: f
- $result = $collention->deleteOne($condition, $options);3 m1 j! r8 d& s4 o& q' s' Y
- $collention->deleteMany($condition, $options);6 G. s# T' q3 Z9 l: E: \& t
2 D- s- m. m0 e8 F- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
% t; m/ s% Z f7 }2 J1 y3 g% Z m - '_id' => $tableName//我在自增表中用其它的表名作主键
/ F; _% Z) ^6 u2 A/ Q8 v. _ - ], [
# Y! c3 N- P# k0 {1 z/ W - '$inc' => ['id' => 1]//自增; X5 o; y) ]" x. v$ D
- ], [
" P# o O, Z! C2 {' P - '_id' => 0
. _, {4 X4 ^1 j9 j7 M - ], [- G5 P8 `# n/ A
- 'new' => 1//返回修改后的结果,默认是修改前的
% W' `/ x+ |; r' M& ~4 \ - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
- @6 C! {. e4 j1 q: Y - '_id' => $tableName; \& q# c0 @& p3 c$ d1 u% w
- ], [6 X3 a( p7 [) u/ _
- '$inc' => ['id' => 1]
5 N# K; a1 T. G+ j - ], [( Q! h! W1 P& x
- 'projection' => ['id' => 1],
) D; V7 F/ _! J2 V* f. @ - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
) n& l5 y* r9 W0 E# Q - ]);
复制代码 $ H: H8 E% f# @. J' }
; Y- q) d. Q+ h5 j
|