|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
0 S0 y }3 V# ^" N) }
) d2 I% M1 q6 v" s- use MongoDB\Driver\Manager;
# m- d* H% d, r2 ?4 ]) b - use MongoDB\Driver\BulkWrite;. i: w% A1 _" u) z( p, {+ `8 \. z+ j
- use MongoDB\Driver\WriteConcern;
5 N- |7 |, V4 g% p - use MongoDB\Driver\Query;
6 |8 g& s" }8 a/ x* q7 v" n) q: ~ - use MongoDB\Driver\Command;' W1 ~9 m2 O0 Q( w
: D' q5 l% B7 Y7 Z- class MongoDb {& H2 m) @# M. ~' Q) }! Q
9 y F# d" f! f9 H; A. J% y- protected $mongodb;* J v# h9 f- y2 _" ^* l
- protected $database;. `$ D5 d0 v' A; t+ R8 u% _
- protected $collection;
; ~$ ]4 E+ T3 u# ]. l% X ` - protected $bulk;( W' S8 C- w; o2 Q3 B. g4 M* K
- protected $writeConcern;$ _5 w6 v- b2 Z9 R1 _( g; ^# a
- protected $defaultConfig0 U; U1 `$ S) r8 Y8 X8 b4 r
- = [
8 K7 w% B+ K9 I, c% H - 'hostname' => 'localhost',3 [6 \ c T# |: A) u
- 'port' => '27017',
/ l& ^" ~6 u. }5 o' @2 B - 'username' => '',
8 O. i7 m- i2 m - 'password' => ''," ^2 z/ M$ g9 l3 L1 ^/ d6 V
- 'database' => 'test'
7 x3 r. Y7 ?& L9 p; _3 E - ];6 I4 @! x4 u. r
. ^# @: O8 G3 ^& u% h( T! x- public function __construct($config) {
# o5 N, v$ H4 H9 D - $config = array_merge($this->defaultConfig, $config);
% m ?2 D2 R6 }$ S# ]6 y - $mongoServer = "mongodb://";/ L# I8 `: e1 Z; a8 r R! l
- if ($config['username']) {
" j/ X7 ^" V$ P9 h3 ?1 Y } - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
! Y" f# f' ]6 t% p' A - }
5 e4 e1 C0 d1 f6 x2 H# ~ - $mongoServer .= $config['hostname'];
5 d2 l3 A/ a, ^3 B - if ($config['port']) {
" M2 x+ _$ [3 F" t& K. q/ i - $mongoServer .= ':' . $config['port'];1 }; g: G1 c. U0 b @9 X* Y
- }
& N e" ~0 Z5 M7 m, C4 S( k3 Y' u' c - $mongoServer .= '/' . $config['database'];9 U3 ]& s4 O. x+ ^
! A; Q5 r9 e- H3 q# i: V- $this->mongodb = new Manager($mongoServer);6 ?6 t8 j( ?! k4 B
- $this->database = $config['database'];
# `. h1 _0 K% m: U, F; W8 y4 k - $this->collection = $config['collection'];
* W' C! _% q _, }$ W# N - $this->bulk = new BulkWrite();* ]6 z3 P1 [' z( A
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
' g" U4 |6 A/ I! y6 W9 A8 X - }. ?) T& K& e& B6 D, y" C6 a! b; Q
+ J t$ Y9 _- Y- public function query($where = [], $option = []) {7 b$ Z6 ^4 L5 L+ [4 W8 k$ Z
- $query = new Query($where, $option);( G2 W' w0 f$ N8 M {
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);& d: B* n" k+ G" k' C* X
/ y+ O9 j* @; i0 A z( x, V- return json_encode($result);
6 X1 }4 H" K8 G/ t - }6 g: j0 V( _) Y7 ?7 I
- $ Y0 r! q0 p& b* E* {$ T
- public function count($where = []) {4 W8 q" z; j7 Z- d) j% {" C
- $command = new Command(['count' => $this->collection, 'query' => $where]);
6 i1 e! B" D: M7 E$ Q$ [ - $result = $this->mongodb->executeCommand($this->database, $command);& Z" [- J5 L- F$ n
- $res = $result->toArray();
: P+ T5 G+ }% g i% m - $count = 0;
. E' Q* i$ u k8 t+ y) Z, X9 w0 G - if ($res) {
3 d/ h9 ~2 t3 ] - $count = $res[0]->n;
& ?% Z- N u1 ~4 J, l3 R - }, \2 Q( {1 A$ a- j1 x& n: \
- + w6 C9 \; N1 l
- return $count;
6 V$ J, w9 G2 Y* H& j - }% F0 o2 }; S2 k& k6 b# M
+ u" Q1 G; `' [- public function update($where = [], $update = [], $upsert = false) {7 l" F5 P. V& w! h
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
p9 ^6 S; u& \ - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);1 ^$ r6 \" o0 O* i6 B/ p
- % S, n) Q% Z" |( r
- return $result->getModifiedCount();
; }9 o3 Z; E" n) F" F - }
. i, w" q5 _$ D' P* K/ r% i - + Z5 Q' J" l. c, N8 `( v
- public function insert($data = []) {0 `2 `6 M# f: [* m. B0 s# }
- $this->bulk->insert($data);; o3 w p5 p& V6 u8 q5 q
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);% P2 N" c( w7 R! }! X1 @1 @
. n: a3 |3 H5 ~3 W a- return $result->getInsertedCount();
* \- e, m* E- N# W - }
# c* x" H. [' o8 ^7 H" t: h - 6 P5 L$ Y" O: x z
- public function delete($where = [], $limit = 1) {1 I$ h5 O. H" o) n% I8 d% ^, N
- $this->bulk->delete($where, ['limit' => $limit]);
- }. ?- S* s% Y7 A$ ? - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);3 P$ h# H7 s$ Y W2 C
) [- \: O3 B: w& f- u6 m$ S N- return $result->getDeletedCount();
' P* Y8 N8 O4 C( w/ [( b7 k- H - }
! V3 p8 N3 h9 w; z. W - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
- H, Z+ s4 P+ S' g a - $lastId = $resultOne->getInsertedId();: r h5 ^6 l5 @' r2 `
- $resultMany = $collention->insertMany($array, $options);//多! }4 P' f3 O8 ~' y) M+ ]
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [8 p! k' _+ h+ B3 r* i! k: ?
- '$set' => $values- X6 K) h7 f1 W% i* O1 }
- ,[7 z- p) i/ Y) _2 \. H8 e5 {
- 'multiple' => true//多条,单条false
. F: `/ b2 V5 w' {: y - ]);
复制代码- 新
( e1 F( H) ^0 D2 S) o1 N4 L
- $collection->updateOne(
, P9 n# m2 i8 a& j8 g0 R6 z; d. j* s - ['state' => 'ny'],9 q0 [# Y! `& `2 t
- ['$set' => ['country' => 'us']]
, M+ r( |' y4 Q5 o2 z% I2 F - );* g1 ]/ y" I4 L2 I' |
- $updateResult = $collection->updateMany(
: Z% c& B' Q0 F5 C n - ['state' => 'ny'],4 `: Q9 r/ R8 z$ Q
- ['$set' => ['country' => 'us']]
0 k: {$ b+ y V( ^# T. d - );
1 d9 s# z: X0 o - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [7 @4 f: l. Q# x4 v1 o+ w/ P
- 'name' => true//指定字段, t4 `% N( M* k& e4 {
- ]);6 q2 T6 h; n* ^/ F" \& e
- $cursor->skip(5);
5 y4 h/ k( |; o1 ^+ z3 J: N0 c - $cursor->limit(5);" Q5 d8 n; R% _4 b
- $cursor->sort([
* ]7 K% H( g% J3 J5 x- t0 t! U - 'time' => -1
* ]0 M. D" o# k+ g$ a2 E - ]);
复制代码- $cursor = $collection->find($condition, [
) c" }! u+ E# g7 a, _* `, V9 Q, r - 'skip' => 5,. v; ^% E* |* K3 h+ V
- 'limit' => 5,! }; N8 W! ]6 ~/ T& B7 R' J
- 'sort' => [
1 Y) J) [) ^* D& a$ P - 'time' => -1
7 j! s; s! h c) ~2 z& ~' X! s6 | - ],//排序
& s: l, q9 M# ^& j4 l, ] - 'projection' => [# V6 B) ^4 e& P8 P3 s
- 'name' => 1//指定字段
. L+ N# J* y! m& d3 k: A - ]
; B1 h& f1 s6 @: g - ]);
复制代码 5.删除- $collention->remove($condition, [- @: ^# Y I% t8 {
- 'justOne' => false//删单条
" S$ f% Z6 z! f3 _. w1 x - ]);
4 D) V; D9 F* \9 G* v - $collention->remove([]);//删所有
复制代码- 新& m8 u6 ]+ e* q$ J1 i) a% H) y
- $result = $collention->deleteOne($condition, $options);/ T' J6 U. Q1 F1 t+ O0 |
- $collention->deleteMany($condition, $options);
2 X5 r: F0 C# ]3 R4 r; H
. g. V- y: ^: k- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
0 D( r+ {4 i) T: o) y - '_id' => $tableName//我在自增表中用其它的表名作主键
5 P- i( v: B2 Q& d$ A' a/ F* @ - ], [
% `7 {6 d! C0 R0 O - '$inc' => ['id' => 1]//自增) d. Y, y/ |6 B+ i% L0 d8 _
- ], [
- m8 o W. O7 f2 H, | [, g* G# P - '_id' => 0
# r$ S( z. C5 k9 k2 v* K - ], [
1 J1 q \* x4 K* Q V/ o - 'new' => 1//返回修改后的结果,默认是修改前的& x9 `0 Z& C/ r" j. `
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
. f z+ C, V0 Q. N# ?' w - '_id' => $tableName
& J; u/ J9 v! ~' u) O# p, l - ], [
$ C; y) A& O: K& f$ F0 G - '$inc' => ['id' => 1]( r: K7 R% ?/ f
- ], [! z- d: @) W8 _1 g1 o
- 'projection' => ['id' => 1],9 X% J0 T5 z: P& U& }2 O
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER; _' g7 `. G) ~4 @5 A
- ]);
复制代码 : e$ }) ^+ I5 V
6 @5 b; f; o, d3 t4 { |