|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php6 W% ?2 x5 P- D( q# ~7 j
8 ] p, f. S# y1 a, \8 H4 @4 }+ n- use MongoDB\Driver\Manager;
3 y3 K9 s) }7 @ - use MongoDB\Driver\BulkWrite;- m$ O ^5 W# s8 f- f
- use MongoDB\Driver\WriteConcern;* V( g0 M6 |* B$ A B& u% b" b3 L
- use MongoDB\Driver\Query;4 G" r2 A+ @/ C V
- use MongoDB\Driver\Command;
& y1 {. P* }5 J& i% l U* g0 N4 E1 K
$ z# d, Y8 V1 s0 Z5 o- class MongoDb {
# ?: G- _ r5 B- B. O
9 R- w8 ^4 _0 ?3 e8 F! T- S- protected $mongodb;: F3 w" x1 u8 G5 W3 v9 _" K
- protected $database;7 h2 L" _- c. g7 D
- protected $collection;/ y0 q9 q& O8 z
- protected $bulk;+ P7 X: Q1 j9 D7 W! C
- protected $writeConcern;
6 m4 a, ~% O, Y/ ~( h" h. Y, h( H. ^ - protected $defaultConfig, e2 l8 c% Z- W, L- R
- = [9 L, O6 s h3 C* ~% c4 t1 Q/ ^3 m
- 'hostname' => 'localhost',
2 I* q) s, _/ u0 ? - 'port' => '27017',
9 O u8 u) M$ Y/ m! v - 'username' => '',
4 ~) M5 h% |: `( U1 ]( _# Q - 'password' => '',
3 W- T) |# _& \! _( w7 T - 'database' => 'test'
" r3 P; z. X5 h+ O+ c - ];) L* P% {0 E' G* @; q0 o& D2 a
7 M% ~, S( o; X* W3 W. k Q; A5 Q- public function __construct($config) {( m# r2 m: j9 ?3 @( Q+ Q
- $config = array_merge($this->defaultConfig, $config);
1 \# f- h( e$ C* F$ v9 { [/ \( Z - $mongoServer = "mongodb://";+ ?$ l; o8 V' r) f+ @- p, Y
- if ($config['username']) {5 @% ~+ R9 `, z3 V# {0 F7 M
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';5 f1 a- |8 @) q) r1 Z" S$ i5 B
- }* F4 e) y/ y( U6 p' q
- $mongoServer .= $config['hostname'];& C) Y, R2 T3 f8 [
- if ($config['port']) {
+ s# } p* N# U4 B6 P P - $mongoServer .= ':' . $config['port'];; S) `( v" C( ^
- }8 |- _( s! I5 {
- $mongoServer .= '/' . $config['database'];2 m5 x' f! j# c6 l# F, J, A
; y6 Q5 I) p( _3 a! K- $this->mongodb = new Manager($mongoServer);
0 ~8 Q- y/ e4 j" e) Q9 ~ - $this->database = $config['database'];
! K& A9 w9 M, Q4 C - $this->collection = $config['collection'];3 s( U3 v& ?+ \! \3 G
- $this->bulk = new BulkWrite();
0 q2 @& D( m. h! m9 N7 J2 B - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);4 |* r% ~4 g0 C6 M% S; ~- _9 H
- }3 e9 j) g) A' |/ V! d* K2 Z/ A
- " P6 z# r* H$ r8 w( C
- public function query($where = [], $option = []) {" P+ H' Y! B7 G+ g
- $query = new Query($where, $option);$ t6 r: m a) f5 U
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
4 u4 D1 s4 M3 Q) N+ R% _: X
8 C! |# X8 v, Q1 D4 F0 D- return json_encode($result);
9 S/ l! U3 F& _1 H+ K" b& {/ ^ - }
" l2 H/ W+ @1 K& l' @, t - ; d, ~1 G+ J) W$ g' N d! H' W. I
- public function count($where = []) {5 ^' ~- O& [, p, H2 @( z
- $command = new Command(['count' => $this->collection, 'query' => $where]);7 _! N2 \1 A0 D9 ?0 x
- $result = $this->mongodb->executeCommand($this->database, $command);1 N* @0 `/ q9 D
- $res = $result->toArray();, `/ g# m7 h- O
- $count = 0;
4 {4 a) B- T0 v5 [1 X; w# H - if ($res) {
: A) m+ ]0 n- @* u2 w9 K - $count = $res[0]->n;+ ~( a# w. i# Q2 q7 c7 k, M P9 v$ Z Q
- }3 I8 v6 | Y- U9 `/ V2 p9 L, T+ [* i
u' R% W! [' M- _6 ?- return $count;
; u. b. R+ z1 y- o; k- B4 _$ V - }
7 Y' b2 I2 f( U# r# D. s
2 A/ M( s1 k+ M7 R" {# |5 ~- public function update($where = [], $update = [], $upsert = false) {1 C/ O% W6 ~2 }, M0 i5 F s/ b& j& o
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
, u8 y( L" P; ^1 l% O - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
# p3 m* ?6 r y' y' I% B5 u - + K+ B2 x+ h4 I3 `
- return $result->getModifiedCount();% |4 C# x! Q3 W5 ]+ B+ u
- }; ~: k! ~* a3 t6 S2 w2 Y( p5 n4 |* D0 o
- / g$ D8 W- j' o4 l9 f Y
- public function insert($data = []) {, B. N8 `2 |) z* K6 d/ u& `
- $this->bulk->insert($data);
0 f f E* ~; `) j+ t: U - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);' \& J5 H S( z( i/ a6 g
k, A% @. ]- I V9 Z, N% D5 n- return $result->getInsertedCount();
' u* U) R( r9 X1 G3 j - }! _8 G$ r' w) }1 r) L& N( X
- " E! C; V# Z# e* w
- public function delete($where = [], $limit = 1) {) U, {/ ^" |4 G
- $this->bulk->delete($where, ['limit' => $limit]);8 E+ Y% K9 G, E& @# M
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);1 a) H1 ^5 c6 r0 H* o
- ' p k7 _4 O/ u3 o
- return $result->getDeletedCount();) @4 P" f! M4 e
- }/ w; ^6 I5 A3 k( ~+ Z
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原
% f, T: n6 o O! Z' r; a$ j& r4 o- K 2.新增- 原8 h4 U, p b6 T8 p0 M. }9 M
- $collention->insert($array, $options);
复制代码- 新
' ^1 q* j: @% h1 O% {. E
- $resultOne = $collention->insertOne($array, $options);//单
% Q7 d) U! [$ E: L - $lastId = $resultOne->getInsertedId();
. \( n, o" \& {, k4 D1 F% _ - $resultMany = $collention->insertMany($array, $options);//多. ]2 r J, T# ~" E
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [0 K5 F$ X* e% S" J! w# v
- '$set' => $values8 r- s+ y* |/ n2 b: b4 B+ e
- ,[8 t& X4 Q4 J% r4 R# |1 x
- 'multiple' => true//多条,单条false: P' d4 Y; f$ ~0 S
- ]);
复制代码- 新
z* T, J4 R# Z' W7 J5 t- X
- $collection->updateOne(
2 I' b/ B9 w4 l7 N' c - ['state' => 'ny'],7 Y8 T: U( O7 @* C3 M
- ['$set' => ['country' => 'us']]
* g9 Z7 c. B$ X' H3 A2 `) l - );3 X m1 D) m' t$ M1 p* |
- $updateResult = $collection->updateMany(: ?$ j7 c0 C1 u8 U
- ['state' => 'ny'],' h& C- ^( g% I3 y* ~2 X0 Z
- ['$set' => ['country' => 'us']]: d) n; J: ]" U, z7 y
- );3 ~# Y6 r: Y- V3 n2 M- G1 T
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [1 \" Y, s; @' C# A f0 a
- 'name' => true//指定字段
0 I9 G" R2 F3 i: ?0 m - ]);5 S7 G3 M8 ~: u) J# I
- $cursor->skip(5);
% Q H5 n1 s" C0 M - $cursor->limit(5);
1 r$ H& Q9 p! M- N - $cursor->sort([
/ q4 l" m o7 u2 I/ S8 w" G( L; } - 'time' => -17 z. h W' Y- y: h- C
- ]);
复制代码- 新3 n; m. y8 ]5 {+ I- H% I
- $cursor = $collection->find($condition, [
! ]- x g/ V+ q# b G4 F - 'skip' => 5,# P1 d' o- c K
- 'limit' => 5,
: D3 q, L- Z/ ^3 o4 v0 I* V - 'sort' => [- ~' n, ?$ @8 r0 }1 `4 K1 K4 f1 z
- 'time' => -1; I, c0 w1 w' {
- ],//排序* Q7 a. X& W9 ]: {: j
- 'projection' => [
, ^! G( Y& D! _" b3 a - 'name' => 1//指定字段# K8 y2 E2 |1 R8 M" }- h6 k
- ]
' \8 t$ h6 b+ n3 Y6 W - ]);
复制代码 5.删除- 原9 y! ]6 k: o7 }& O$ b; g* l' [
- $collention->remove($condition, [
' U# n; p9 M6 Z% P; w. t+ _ - 'justOne' => false//删单条- T8 C8 |0 s" N, }2 K* s, S
- ]);
' R: `. ?' y0 N, Z. D4 m$ [ - $collention->remove([]);//删所有
复制代码- 新; l& s' y5 @, n" m6 a! q
- $result = $collention->deleteOne($condition, $options);. d0 P% i7 ?# d
- $collention->deleteMany($condition, $options);
, B2 j6 ~. [1 ]( h6 O
' y; v8 Y2 M3 R) @7 {1 E. _- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([7 X) P6 M2 G R+ P. C
- '_id' => $tableName//我在自增表中用其它的表名作主键: X& T0 O5 A; |8 j
- ], [& d: d+ z+ _2 L
- '$inc' => ['id' => 1]//自增
8 Y5 L t2 n/ l* D! k& T, W - ], [
% l$ x( C- Y& T) K* @2 ^ - '_id' => 0$ y5 p# `$ Y# }& g" G" X
- ], [, g1 c; T/ b1 t* g
- 'new' => 1//返回修改后的结果,默认是修改前的
, D' B y) ^4 L% g* m - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
* `3 Z2 E3 z& U7 {2 _) h# \5 n* K - '_id' => $tableName- C8 F, F* S4 I1 c+ g1 @# s
- ], [0 ?3 O& k# m4 e8 ?& p0 R
- '$inc' => ['id' => 1]
" S. |3 G/ V$ E! s/ u' @7 q - ], [3 D4 J: ^- ]& C( f
- 'projection' => ['id' => 1], p d/ Z7 t2 c1 b3 ~
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER" y4 j, K7 A1 U. M9 M$ i
- ]);
复制代码
; B" k4 R! f) k+ n# }. R* W, i
t7 q$ b& F. @: s7 h) h; y1 {9 X |