|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
5 D6 y& k0 p2 I3 h - 2 s+ S* V" H C7 N
- use MongoDB\Driver\Manager;% f8 B+ K% e$ w+ o! m! ~0 D3 R
- use MongoDB\Driver\BulkWrite;$ `9 H* K7 P. O5 K% [
- use MongoDB\Driver\WriteConcern;
' _. G) E3 d; D; w. X$ r - use MongoDB\Driver\Query;9 \1 T- C1 M8 ^9 B) T* H
- use MongoDB\Driver\Command;; W$ R& r) n; F. X# O5 S
- , C" E6 Z, s7 n' l% H' E' t* K
- class MongoDb {
0 ] U+ x4 U& j
- P+ x3 u1 D+ p3 x6 m- protected $mongodb;
' s" S' D2 l3 B; V& } - protected $database;
+ K0 m0 }' H: p# E# @ - protected $collection;- u# j7 c% i, y8 k- R
- protected $bulk;9 [% b9 `8 O" d& L3 X1 E7 `
- protected $writeConcern;
! H) Z) G Y; {4 m$ F _ - protected $defaultConfig
r- y4 h$ U. {) n( P5 m2 u - = [
/ {$ j, h9 s, H; ^2 I) } - 'hostname' => 'localhost',) |; O9 b1 t# L7 h/ ~$ S
- 'port' => '27017',
% W4 J% Q* F1 @5 C B+ L: t - 'username' => '',
7 O: W9 c+ d$ ^6 h, t/ d" O0 X - 'password' => '',4 h+ Z) k# ]7 n/ {) Q& V
- 'database' => 'test') g6 Y/ O! z# x6 L+ Z+ u5 c; W
- ];
1 ]* H' n8 d( B3 P - 5 H. g2 L$ E; q# ^& }! j/ G
- public function __construct($config) {; l) k# J3 m) Z/ N- j
- $config = array_merge($this->defaultConfig, $config);
0 j5 ]& [ [* K - $mongoServer = "mongodb://";, e' k3 p: ~6 v6 n* Q0 I1 [4 J6 R
- if ($config['username']) {3 L& D3 L7 D9 q& j5 @
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';5 x @& ~2 z5 h4 L
- }) _. j9 _+ E5 j0 S
- $mongoServer .= $config['hostname'];
2 Q4 m5 E" \9 ~" |; e - if ($config['port']) {8 [9 ?$ I( K6 ^5 S# |: z
- $mongoServer .= ':' . $config['port'];- \) \7 W3 x4 [% F1 l3 k
- }0 e. D% U5 Y- D$ e! o+ L, j
- $mongoServer .= '/' . $config['database']; {9 _" g* x H& f; B, ?3 ?
- $ w+ ^6 K& K3 P- C* M
- $this->mongodb = new Manager($mongoServer);( T2 @( `7 E" ?6 W' y% r8 T3 z& [
- $this->database = $config['database'];
3 v4 o9 o* E& `5 s" Y# \$ M - $this->collection = $config['collection'];( l3 `1 v, j9 Q p5 W* y2 L
- $this->bulk = new BulkWrite();
* a% d. G* w' M+ E. P7 e* ?/ H6 H - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);2 ^5 f, ^- z3 |9 }6 s: y. u. |
- }) l1 o: X: f; F! k: ]. y' w
$ X5 ` b- H' ^3 m7 A- public function query($where = [], $option = []) {, A5 o. R9 g+ T& K% ]/ W! A7 t
- $query = new Query($where, $option);
1 V& {( q" \; H* s - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
3 R. j- o( b/ X3 S( X4 y c
U |- j: T0 J$ T; ^3 @( f- return json_encode($result);
3 n( o3 f! r4 z0 L& r+ M: c& P: e - }
+ ^1 @$ Y- w; B8 l4 S
" G' G/ N8 K- r- public function count($where = []) {
& V$ k. x \& z, c5 B - $command = new Command(['count' => $this->collection, 'query' => $where]);# Y* {9 D1 Y' g- Q" T3 G2 v7 {
- $result = $this->mongodb->executeCommand($this->database, $command);* K# T/ a1 K$ h0 h% u
- $res = $result->toArray();$ G3 l: U4 T7 U. w( `
- $count = 0;
% {7 A6 @9 }5 I/ K$ l - if ($res) {
- M( ?* w4 o5 G V% Y S - $count = $res[0]->n;$ }, h& a, m4 w3 ~3 ?
- }0 h" e# w4 m3 x. q3 b8 M3 W$ H
# o! x: L9 s9 v1 M7 H/ y; g" n- return $count;# V- P5 g) m$ B& J
- }# O5 e( Y( S! r( C& z
- 3 Y1 x+ _. M/ r" B) ~( S# W( L+ m
- public function update($where = [], $update = [], $upsert = false) {" |2 j6 `1 G: _! k" p5 `: ]) U
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);. t' p, a7 d' p5 G+ S6 H
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);& A, R% {& U. `/ b. ?1 `: I
- - c. l% N$ q2 v+ V, Y
- return $result->getModifiedCount();5 x) t! [# g1 f1 L* ~1 _, h6 [
- }8 i9 L" U. n! ?% j; K
0 I5 h R- I; i- public function insert($data = []) {- X0 O" Q' ?/ n6 q
- $this->bulk->insert($data);
# T$ ~- w8 ]0 m a" x/ Z) [ - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
) O& i. n" i% s7 Q
I8 P0 R n: _& {, L' r% p- return $result->getInsertedCount();
/ K; o# }1 G1 {/ W& U% K2 ~( D - }
( `8 b0 v5 B% N1 S* v6 x; w - & {3 |& n7 T0 c, i
- public function delete($where = [], $limit = 1) {
- ~& H; f$ l; c! }2 p1 d( f - $this->bulk->delete($where, ['limit' => $limit]);
1 \2 k: C J" N) H: D' C - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);( T* q4 V8 {( k$ W Y
- , H& U6 y0 v- u* F& p
- return $result->getDeletedCount();' w/ x4 y$ e, n$ ~4 T
- }
/ M! P& L) \4 O+ G' {' U( ? - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原( |% V( ]: u2 c! [/ j- e9 b
- 新+ B7 Q. ~+ w' g! y9 _7 N7 @1 L
2.新增- 原1 j3 ?9 X7 |4 K' ], `. T
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单8 g9 w" }8 A8 a. X* ?/ k
- $lastId = $resultOne->getInsertedId();
/ F _0 i, u1 k: n - $resultMany = $collention->insertMany($array, $options);//多 _) p( Q6 D8 W e x9 l+ t. H9 f
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
7 ?) @1 M" J- E3 y( \* R
- $collention->update($condition, [' R; g' _" m8 B" q9 H
- '$set' => $values! j/ Q6 w, y' @% o6 S6 U" t) l! f
- ,[' z5 S- b& l& L/ M2 ~
- 'multiple' => true//多条,单条false" N: R- o7 d m% y9 X
- ]);
复制代码- 新
6 L. W/ ~8 I/ k9 ?' X* e
- $collection->updateOne(
8 P" b3 S% r2 U1 V; [: ^& S - ['state' => 'ny'],
8 L$ v/ d5 f* f" v - ['$set' => ['country' => 'us']]2 ?2 u; M! J7 e( d$ g1 o; n, Z
- );0 n6 j& P4 M7 ^$ z
- $updateResult = $collection->updateMany(' Q1 }$ l3 K# Y; {7 ?+ z8 ?9 l0 y4 ?
- ['state' => 'ny'],
+ {% M2 E4 n5 h5 j1 V# w, C - ['$set' => ['country' => 'us']]
; r j/ H( K: e" u - );# g) U' A1 H) c2 h! z
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
! n6 e. V( c) P7 m; j - 'name' => true//指定字段5 u. v+ A: i z$ d# q2 |4 _3 j
- ]);
$ k7 L+ z* A' a( V2 h - $cursor->skip(5);
4 y% p5 V( f M - $cursor->limit(5);/ F# N$ i* E- {# O- ^( S
- $cursor->sort([
6 }. ^" O5 i2 D, s* O) \' x7 ?2 a - 'time' => -1
1 v! }5 v0 H0 n9 Z, M7 @# { - ]);
复制代码- $cursor = $collection->find($condition, [
0 u. M. ]* M4 C! g# j& A - 'skip' => 5,+ p( A$ {) l- ]: E$ l; R
- 'limit' => 5,
. P+ F+ U. W0 M- }5 f2 ~ - 'sort' => [
- ]* {; H& n6 w' h* a" Q - 'time' => -1# K+ u. d( Z7 A8 A7 C* c
- ],//排序+ M8 u5 u2 O1 R* J0 Y
- 'projection' => [5 d5 ~/ [! ~6 p r4 y0 m
- 'name' => 1//指定字段0 ~8 ~, N! o9 R6 N2 U! u" V0 ?- e
- ]- J1 a7 i1 `, q" i( `
- ]);
复制代码 5.删除- 原
2 b) G2 [; h7 R/ O3 u! F
- $collention->remove($condition, [
|$ y1 ~5 }8 w" _) l, ?( A - 'justOne' => false//删单条: t! d( I1 `4 z' X; Z
- ]);9 n9 o" x9 C" E6 e$ K3 ~! T" Z
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
& x* L* s2 h( x! R9 B G! ^" B - $collention->deleteMany($condition, $options);0 d2 N: I2 x! i* A7 ]* o% w1 O! F
8 y# M& r& r/ H9 j4 M2 W8 G2 ?- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([! p: N8 @+ ?- l0 l5 i6 o. t
- '_id' => $tableName//我在自增表中用其它的表名作主键6 w# _* t0 A5 {$ R9 w5 V
- ], [* y6 u# N+ c: {# W) `+ `- A
- '$inc' => ['id' => 1]//自增
; E# _/ M0 r4 `: m9 }7 s8 ^# | - ], [/ U$ ~/ f' P \! ^
- '_id' => 02 ~4 ]+ {& r, Q0 B0 Y5 a" @! M
- ], [
! d( |" m2 y. K" N1 r0 S* U - 'new' => 1//返回修改后的结果,默认是修改前的/ T. c' \ D" T6 X8 x
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([0 H# a/ S+ F1 {; S, l9 M
- '_id' => $tableName
7 r) @% k& _$ s& J+ p; f - ], [
% O' A6 h7 }5 X( d, e - '$inc' => ['id' => 1]0 |* k3 l$ C3 V
- ], [7 j4 l) `( q' W* [
- 'projection' => ['id' => 1],
, }0 y' n1 R/ N- f- J - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER8 ?+ b' Z H6 ]4 G
- ]);
复制代码
8 z3 E1 s! F/ c* Z$ I v, y! W9 {9 F& a0 `
|