|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php) f1 S. f- @8 G7 a5 k
3 q. K4 ^! Y% d: [- use MongoDB\Driver\Manager;
. b3 m0 K$ s S' F5 m - use MongoDB\Driver\BulkWrite;& F& f7 @3 _7 V5 S+ p: H0 K; k
- use MongoDB\Driver\WriteConcern;7 b) w1 D: X+ E1 D* @8 K5 C( h
- use MongoDB\Driver\Query;9 s! }2 p% g+ i5 z( @
- use MongoDB\Driver\Command;
/ K; H# O) R8 ^/ y
4 D) Q/ J2 C3 p7 y- class MongoDb {% P3 T6 O$ }; v% O) T, L% l) U0 ?+ ]
" k8 |, {# y8 k" s& ?9 |# }- protected $mongodb;4 K$ w: D$ u7 T1 h% J2 f8 R
- protected $database;
, W, b' W- \$ R) A4 w - protected $collection; P4 x# y% O$ G1 M+ P# |
- protected $bulk;
% B$ y9 r& y w* b - protected $writeConcern;& F3 L$ o7 E3 M0 P5 @
- protected $defaultConfig
4 B, [, L( @" j' q9 t* V+ L - = [5 y8 p/ Z: [9 k/ g j% F& e6 Y
- 'hostname' => 'localhost',
+ m7 m$ i0 Q3 ]* m+ O - 'port' => '27017',; T. P+ {' H9 ^
- 'username' => '',6 C/ y1 q4 N: D) w9 ~5 h) x
- 'password' => '',
) Q4 S) l( ^) G" N& } - 'database' => 'test'/ R4 D# R+ [7 P0 t
- ];+ w1 j' [9 _& {8 x: v0 T7 m
9 t" g6 Q. h8 n4 T( W4 g3 I& \- public function __construct($config) {# k5 l3 V; b( y
- $config = array_merge($this->defaultConfig, $config);
1 g* j6 B; r5 N* W7 i - $mongoServer = "mongodb://";
% @! A3 J6 g$ @0 [0 x - if ($config['username']) {1 D+ V; [: H0 J
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
~1 U2 a( C. d/ _ - }
+ Q9 d3 G; D5 w6 A - $mongoServer .= $config['hostname']; j! N- E d" c' v, e6 Q0 @/ Y6 I
- if ($config['port']) {7 `) p# K% i2 g- ~) A, P
- $mongoServer .= ':' . $config['port'];
6 ?- b/ m' y8 t - } q* K0 S) q, D6 J) T
- $mongoServer .= '/' . $config['database'];
I8 B7 B9 n% R; R - " \5 Q: B& a0 A0 M9 Q; ]
- $this->mongodb = new Manager($mongoServer);
' q, y2 `$ s9 a5 S5 \8 F - $this->database = $config['database'];( e) V; q5 b, x- T
- $this->collection = $config['collection'];8 p$ v4 D! A2 }; b. l6 {2 U% X
- $this->bulk = new BulkWrite();! E9 |$ z# `) W6 J
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
7 `" O5 P5 u8 y6 J, h6 B1 D+ Z' f' p - }
k* N3 j+ J& _" l: m: m1 b
5 C+ \# t1 z5 n- C; @- public function query($where = [], $option = []) {
. T* i3 @! P! F" }5 s! y - $query = new Query($where, $option);- y; [5 x# c% j6 Y$ M- a( s' h
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
4 O1 f& O0 C, |& G5 m+ {/ y4 S$ _
+ z+ s9 E- g, V. q, J$ v' E5 G- return json_encode($result);/ R# R! s1 e% Z9 C
- }
% ^9 h! {- j, e" f - ! Y/ q+ d4 s* R3 U e6 J% S
- public function count($where = []) {
! |: A, g5 h4 I6 B' r7 a - $command = new Command(['count' => $this->collection, 'query' => $where]);
% H* k$ c+ M- ?; j: [- e - $result = $this->mongodb->executeCommand($this->database, $command);" o7 `* O* Y1 \$ U `
- $res = $result->toArray();
X# a1 g# c: o! b - $count = 0;1 f& K! d' T) c
- if ($res) {
* d6 U: T* L/ }! n- k - $count = $res[0]->n;
y1 t. e. T0 v4 B m& u7 G- o - }$ z8 P) l, p/ b! t3 y0 z( X7 ^4 j
- 1 b: T' L9 P. a" A* `" Y
- return $count;
4 s) i8 d' t0 M& { g6 h - }+ G( }* Z/ Z1 i2 v* O
- + u/ G. }' C" N0 e' W h0 _
- public function update($where = [], $update = [], $upsert = false) {: S, {5 p# R5 s- Z
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
" e+ x% E f" u - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
) ~9 L1 U! L( l - 0 T2 H; D* R1 ?& P
- return $result->getModifiedCount();
! w6 T1 Q- m: i5 N1 D2 L - }3 P5 A/ F0 l0 k) `4 a' J3 x; n* \0 j
- }* r. C+ D0 E1 c- public function insert($data = []) {
0 o1 X, g! ^( d% m# e% N0 J - $this->bulk->insert($data);3 J0 L2 F s6 a( }
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
& D- M9 ]4 n' }; \3 M$ V5 T - 8 {0 w6 L* T- S) I L
- return $result->getInsertedCount();
2 q) u6 _7 o' y - }6 S2 G" y* H r# k7 k7 v' M2 y% w
" w( G; \# j2 r+ N9 ?' y2 q R3 I- public function delete($where = [], $limit = 1) {
5 [; B( m; v3 j& {, `# }4 ]& z - $this->bulk->delete($where, ['limit' => $limit]);& J0 M" t% h! f! L* r# G9 r
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
' w2 x( m9 a5 f: F1 H - . w7 v* ^ B- j8 ~& f, _% m
- return $result->getDeletedCount();
9 |3 l, v* R7 I, @( [, x - }
, X9 ]1 |: D7 B- ]- x5 k - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接2.新增- $collention->insert($array, $options);
复制代码- 新
% l ?& d( ^) P7 Q0 T) t
- $resultOne = $collention->insertOne($array, $options);//单# [. B* E7 \* G3 u
- $lastId = $resultOne->getInsertedId();3 i4 v7 [+ E' V' _. b1 Z- A9 O
- $resultMany = $collention->insertMany($array, $options);//多
9 i: e; Z2 F! U! ~: y) D - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
3 M5 E; g: H( d( i: A( g% q. u; B3 Q! k
- $collention->update($condition, [
/ @9 h, q9 Z: H. e9 C* y: X - '$set' => $values+ `7 d6 T2 A: f$ j2 O; @
- ,[5 o+ l) u* d. a8 y `4 ~/ G
- 'multiple' => true//多条,单条false
2 s0 ^+ i, A9 S6 ]$ Y - ]);
复制代码- 新' i0 `8 [' R- E1 M+ K5 Z: M! C
- $collection->updateOne(( \5 g/ o: x. ]
- ['state' => 'ny'],; i' L( Z+ z# K+ }4 o$ @
- ['$set' => ['country' => 'us']]& G* T* D4 d$ ~/ v& c/ u
- );
4 X4 F5 D" S7 Y% k1 f: T; j' {0 E - $updateResult = $collection->updateMany(
" K: L E: Z* t; ?, i7 ^; R - ['state' => 'ny'],
+ k$ R. x0 ^( p/ ?3 p; H& h - ['$set' => ['country' => 'us']]
8 L/ n8 z; |# j9 B2 ? - );- r/ W# f; ?* _2 c0 j+ J
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原9 s/ b' \" D4 j8 E3 ^2 K+ t
- $cursor = $collection->find($condition, [3 D2 t* D, b& y( ]' A
- 'name' => true//指定字段
2 R% }, Z- c' z7 {- X$ c - ]);+ q- m( x$ i1 k- q
- $cursor->skip(5);
6 P" H2 e5 ^3 D& ?2 ^! B+ |7 u - $cursor->limit(5);
* C8 w; @; g6 I/ C0 U( Q - $cursor->sort([. ]2 d2 k0 p* k- R+ {$ _8 ^, l' F* J' _
- 'time' => -12 L; l& `0 ]: t! h
- ]);
复制代码- 新1 b3 m# B$ G. ^/ i6 R5 A+ K( K
- $cursor = $collection->find($condition, [8 P# _4 U) _+ F; u
- 'skip' => 5,) K, q9 L5 m+ e
- 'limit' => 5,/ S/ k2 [3 I! E) B3 p. ?
- 'sort' => [
3 l) I) i, T/ V, ~! H- t1 F8 H - 'time' => -1* i3 {6 d0 S' y1 V. t i
- ],//排序" E" C+ ^/ C0 ^; G ?1 C! I- |
- 'projection' => [
% _6 |& G/ O$ B, u- j3 P - 'name' => 1//指定字段
! \0 x6 J; r- K$ m. y" E7 v - ]
) x0 O9 \$ b8 @ - ]);
复制代码 5.删除- 原
; y" t9 B' t! L& O4 \( @
- $collention->remove($condition, [6 w7 |' T1 C- G; w1 X2 H7 M
- 'justOne' => false//删单条2 O, W5 J. m; E9 H* D6 N* @
- ]);
( O8 z5 @# t l% x4 U7 q - $collention->remove([]);//删所有
复制代码- 新
: R4 p& h. {1 E( c9 g; P3 B
- $result = $collention->deleteOne($condition, $options);
% g- D9 G' S( n5 X" Q" b+ B - $collention->deleteMany($condition, $options);4 `: H0 ~4 f1 n* d$ `& n
- 3 [' E, X/ l* W: I
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
$ e ?* H9 o' R0 q) L h! H - '_id' => $tableName//我在自增表中用其它的表名作主键! e+ W0 s! A+ e8 m
- ], [
! q" G: @2 l: M - '$inc' => ['id' => 1]//自增
' y( g+ c( H- h" j, d - ], [4 t: a; O }; W9 ~. K
- '_id' => 0! V' Q( R: z& T
- ], [
1 d* y( j- ~8 V: h$ A( @ - 'new' => 1//返回修改后的结果,默认是修改前的
8 z0 M$ p t! }2 N - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
5 E, F: T6 c4 B; ^7 k - '_id' => $tableName) N" p" u1 ]/ Q9 V Z7 @; J( z
- ], [! }& ]8 D5 m- v; Q9 S! {0 ?' d3 ?
- '$inc' => ['id' => 1]
6 K2 m7 x; G& X* k5 u3 T& B; b - ], [
% C3 F' |; y R# \) J" C - 'projection' => ['id' => 1],; e0 f8 ^! I ^6 ?' N4 e6 N$ y
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER8 S$ a' A: ^: i, x0 @
- ]);
复制代码
9 H8 l' [! O, c6 ?. b5 l. J' V; u$ x4 n" t
|