|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php7 X6 ?8 o' G; \$ x/ l* x
- ; K |/ b8 Z) Y+ O4 L+ u
- use MongoDB\Driver\Manager;4 T3 N" X, i+ e$ v! b- R6 s
- use MongoDB\Driver\BulkWrite;
* ` J9 A" |6 Q: B) s# V; p - use MongoDB\Driver\WriteConcern;
1 A& ^9 V. L' t' U$ E, |& q2 }) M - use MongoDB\Driver\Query;
d/ g9 T+ T; q& k4 t" o3 U& c. Z1 Y - use MongoDB\Driver\Command;
3 M' [: s1 L( W
) c& _: F4 q1 ^1 E$ Z' V0 @+ i- class MongoDb {% s% _4 w$ \/ F7 C# X/ Y5 _' y- G. w
- . x$ S, I3 `: ]3 a) c( L7 Y7 N
- protected $mongodb;
% [6 Z. h+ i, I0 T0 y! J - protected $database;
5 U6 A. U: X4 f- y - protected $collection;4 ]$ M8 h Q. X+ I( J! N
- protected $bulk;1 m; T' b8 b4 h% s( Q
- protected $writeConcern;3 w& Y. n$ w3 u' \) _
- protected $defaultConfig- S9 X7 d8 Y. e: \8 M* N
- = [4 s J" m, a% A/ v: B
- 'hostname' => 'localhost',
- s4 c7 b# x h& W - 'port' => '27017',# g. r2 `. ]: o( ~% A
- 'username' => '',
; O: i) [9 s. O& {1 ^ - 'password' => '',6 l) P1 z) b( c+ b7 ` B: ~+ g
- 'database' => 'test': \$ G0 z% x* O. L% B
- ];
9 C* m0 H9 v @, K
7 ]3 S/ S( g! J! Q* @6 z- public function __construct($config) {
6 C! A; R- x1 |6 r8 C. ~ - $config = array_merge($this->defaultConfig, $config);4 U! _8 W5 T4 q
- $mongoServer = "mongodb://";+ V) C& \0 p. O3 O
- if ($config['username']) {
$ }0 I1 _+ S3 S; \4 z2 d - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';7 y+ F1 e$ z' Q# V) S# Z
- }' l& V9 A5 ^( y$ r9 g d0 ] r$ J$ Y
- $mongoServer .= $config['hostname'];/ {: s0 L1 A' `: _( k7 E4 g* F
- if ($config['port']) {! ?! |6 J6 F& B5 ~+ c- R I, O- w
- $mongoServer .= ':' . $config['port'];% f5 b c* ?2 n: w/ y; u2 o9 I
- }
( ~: K" P0 }( I2 m2 n; _3 J( ? - $mongoServer .= '/' . $config['database'];
0 Z7 J* m' Y4 f" {; Z8 D - 4 _" [1 Q! k- a$ m. ?3 D- y& Z9 E
- $this->mongodb = new Manager($mongoServer);
4 b/ h8 I( `- y% q4 @7 l! G - $this->database = $config['database'];
. ~: z* Q# c4 p - $this->collection = $config['collection'];
1 o0 B7 A+ S9 ]: V - $this->bulk = new BulkWrite();& x6 ]) [3 ~0 D5 B' w" R6 o0 f8 o
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);1 s; L( C B( K3 k! q
- }
, z6 {: ]! g$ V, p - , M5 @, d$ |1 Y2 f; p/ B, g1 [
- public function query($where = [], $option = []) {: u0 v5 `! A& S
- $query = new Query($where, $option);6 h" f& P+ W8 W5 P
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);6 H+ E; d6 a4 C- B( G9 h) g$ i
- ( M2 f4 k8 G& j) w4 G
- return json_encode($result);
" z( p6 X- Z8 O' I - }
' R& r+ S+ h! g# l
! U7 g7 A* g8 ~% l+ _4 r) T- public function count($where = []) {
9 v6 r2 G, y9 j( a. g - $command = new Command(['count' => $this->collection, 'query' => $where]);
9 p# C7 ]+ k' f" \: R H - $result = $this->mongodb->executeCommand($this->database, $command);$ Y; {( y' p; ]# j' r
- $res = $result->toArray();8 G3 y& J5 U3 h8 f
- $count = 0;4 }/ L5 Y1 V" w# }. R
- if ($res) {3 T9 X4 U* g! D
- $count = $res[0]->n;
$ U7 r2 O! `6 {% n - }
9 x8 T+ V, s( \- g+ J
3 U: j0 X$ W' N- return $count;" i) [% g# J% ]) l
- }" e# p$ g/ o( b! s1 F2 g0 a
% N5 o) u ^. E4 z" X- public function update($where = [], $update = [], $upsert = false) {
( v' [# N4 W7 k/ r - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
& m/ S, I- [& T) s8 N6 d# m7 Y5 v - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
7 x* a- }4 S+ N4 X0 W - 5 z% T' u i$ {0 _; r( V
- return $result->getModifiedCount();
! }0 V* \! K o+ @* p3 O - }
& P- v! [7 D, q8 F8 J$ ~) M( W# Q
" _1 `3 P& J: Z5 U* \- public function insert($data = []) {( `; e/ P* P/ k7 a1 J# z
- $this->bulk->insert($data);
- s. x9 k) H( N9 M8 U$ `* l( G - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);8 f9 ~# o, T! p! `/ _0 ^& \
- + w/ A) W$ x, g5 i
- return $result->getInsertedCount();( ]; ?4 o$ P2 K, _( A0 ?0 T/ ~
- }
- k1 ]! p2 n2 s! S - 8 O& S3 A; K. J" k
- public function delete($where = [], $limit = 1) {
# b$ w# T" R* y( B' K - $this->bulk->delete($where, ['limit' => $limit]);
# ]! |& E2 c" v, S2 [ - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);( g* C+ h5 H3 y9 ], N
" n/ A5 K6 k3 u2 W! \, G4 G- return $result->getDeletedCount();
0 i' R8 c8 T( N g0 B - }$ S R$ c6 S& O' I
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原& A/ W+ V+ q& }+ B4 e7 g I
2.新增- $collention->insert($array, $options);
复制代码- 新
! _. v5 g9 }1 d* m% [$ Y4 Q4 z
- $resultOne = $collention->insertOne($array, $options);//单! ~! x# F) O5 l6 P- r0 e
- $lastId = $resultOne->getInsertedId();9 K" F9 Y, A8 g/ { H- u
- $resultMany = $collention->insertMany($array, $options);//多- G6 L" w* A; D+ F1 Y3 J; p
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
, k0 r. w/ [$ X& l# g. E- f0 m( m
- $collention->update($condition, [6 }& o" J$ {; N5 A
- '$set' => $values
1 |8 Z7 i' w% p - ,[
) I% c& ?5 v6 S - 'multiple' => true//多条,单条false1 o) f5 c2 `, z" i! @
- ]);
复制代码- $collection->updateOne(
: D. J$ C# H3 D# W; z1 B - ['state' => 'ny'],
7 r4 s. N1 d& |5 i - ['$set' => ['country' => 'us']]
) X1 W1 ^1 m6 x6 P5 J - );
& W( I% l$ v& R; w; F0 `3 M! b; `- t - $updateResult = $collection->updateMany(
- k4 o3 o, D' T+ j1 f- z - ['state' => 'ny'],
# C- [9 |3 }0 H8 @ g- W - ['$set' => ['country' => 'us']]( g' `; |* ]$ J) C/ _+ P6 N% T$ O( @* T
- );3 s/ I4 u! m6 r, }) y
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
; d" t) Z. c! S1 [# R1 p - 'name' => true//指定字段
$ }+ L, F% B& k - ]);2 E" m$ q( A$ v0 d' ]( E
- $cursor->skip(5);
* Y4 \7 i* ]2 l0 h7 H- } - $cursor->limit(5);
2 r% S& ]8 |, F7 F - $cursor->sort([
V# A0 ^' q0 X& u* } - 'time' => -1- W7 t% }$ p- i. f/ ` {& j
- ]);
复制代码- $cursor = $collection->find($condition, [. \# s/ T1 L* t9 q
- 'skip' => 5,
; d3 x" X, M" Q c - 'limit' => 5,
- `, a1 G( v r/ B2 \ j - 'sort' => [
, c+ U( S; O0 k& t+ ?& ^ - 'time' => -1
4 H- Z8 [8 X1 L% `9 A T; s- t - ],//排序
% ]$ O9 m8 C) w* w) ?! J _& U - 'projection' => [
9 Y1 C$ S, G0 e; M, `8 J9 C - 'name' => 1//指定字段: L0 n2 v2 Q+ R8 m9 R, D
- ]7 M; s0 i( Z! Z5 m' h
- ]);
复制代码 5.删除- 原; M% L+ f t1 @: g9 z( l8 i) R
- $collention->remove($condition, [6 @& K0 i) u* e$ V) M: l6 c- x
- 'justOne' => false//删单条6 j; b7 c, |8 q' m
- ]);: K$ Y6 R; g7 _, g/ _# w
- $collention->remove([]);//删所有
复制代码- 新# h" p* I7 l/ ~5 ~' `9 m
- $result = $collention->deleteOne($condition, $options);* q P; p+ R9 h1 A
- $collention->deleteMany($condition, $options);7 V( Y! h3 Z2 ~5 I# o) x1 ]
+ X) L8 M. c' N1 c- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
$ b% S6 p# K/ K$ W& _' {+ k) I - '_id' => $tableName//我在自增表中用其它的表名作主键8 K" x% M% h. D4 Z# A' K7 M
- ], [' G1 D$ [( W; G: z9 t5 v
- '$inc' => ['id' => 1]//自增2 q2 F! J4 k4 r
- ], [& z( ?& V2 W+ t, f7 m% {
- '_id' => 0: f8 P. B# W, ]
- ], [
" i. k# f2 l' @: V - 'new' => 1//返回修改后的结果,默认是修改前的6 g5 q1 ]& W1 T1 {0 v8 d
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([# [! h- n4 o+ B; F" ~
- '_id' => $tableName
( `& a6 t' h# y - ], [
" F5 c# {# ~- ?5 v2 h - '$inc' => ['id' => 1]
7 R. A0 {/ Z: b# s' T! @ S' k - ], [( ^8 T+ V a0 G' a5 ~9 x2 X2 W- \: e2 e
- 'projection' => ['id' => 1],5 Z1 |; Y( d7 E: g
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
& i! ?/ E& u/ `7 M: K. b, { - ]);
复制代码
& m5 u. A2 L6 w! ?% J3 H0 N# L+ J: R
|