|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php$ }$ |" a9 J# [( u
- ; V% V, Q. F6 m# E
- use MongoDB\Driver\Manager;
; }( L! P' i$ n; D% D% P! X - use MongoDB\Driver\BulkWrite;
1 |( U& ~- z4 ]6 W4 G9 w* I. o - use MongoDB\Driver\WriteConcern;$ d% y- D, N( H
- use MongoDB\Driver\Query;
6 D6 F& Z$ N( }6 K K% N - use MongoDB\Driver\Command;
! e2 W$ ]2 l& E& ~ - ! c- i1 N) P( N' J5 J: d
- class MongoDb {4 }% H: c' g/ r2 K/ e
- ( r2 H2 O% t8 d; L
- protected $mongodb;
, T# h. F6 S' P- z - protected $database;" W: O# S2 M9 x2 P+ k
- protected $collection;
* [" a( `( b) H5 \3 V - protected $bulk;
9 Q, O% o2 z' Z+ ~+ w% @ - protected $writeConcern;9 `$ Y. f! p, w# T! y
- protected $defaultConfig
2 ]2 U* K5 s; q: k# N8 J - = [
1 o# P$ {. q' }, E. Y - 'hostname' => 'localhost',0 w9 o1 H% S0 A3 R; k
- 'port' => '27017',8 k: b7 U# G0 K+ P4 a2 v" \
- 'username' => '',
: v4 Q' L3 ]: k$ G3 B# u: h3 h2 Q - 'password' => '',
4 S1 h- n( l+ ]- m; { - 'database' => 'test'
$ O6 d5 u3 T4 }2 _+ d2 H - ];# z. Y9 Y% `* x* d6 |
- 5 F6 C2 e4 R4 [- D: g
- public function __construct($config) {, R- L; a; [% i& X
- $config = array_merge($this->defaultConfig, $config);& F" p3 W5 e; L4 X, p% o8 ?
- $mongoServer = "mongodb://";/ k c6 \$ q/ k; m; x" V: q" U
- if ($config['username']) {
$ x( p: J* L% O8 }6 k8 u - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
# A$ z! y6 w$ u7 [ - }
! z& A" I3 ~# X - $mongoServer .= $config['hostname'];1 C- K# v3 x, {* m) E
- if ($config['port']) {
) G8 N$ H1 G! m0 K% V# J9 G - $mongoServer .= ':' . $config['port'];
% W0 U# k# ~ w - }. v( {9 T- o' q1 M8 |( J% x9 [# p
- $mongoServer .= '/' . $config['database'];
/ M# s3 E3 z9 t" W; x - - ~6 N! f# R7 \4 c, k2 S2 V2 S
- $this->mongodb = new Manager($mongoServer);9 c5 Z- Z7 C8 x* g% N
- $this->database = $config['database'];6 Z+ {- P& i; g6 x: \& A
- $this->collection = $config['collection'];
" o. f1 A! S$ t$ k - $this->bulk = new BulkWrite();: M0 ^; u! Z3 P4 w4 c
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);! F" m3 P7 ?$ Q) ] L v6 g
- }/ V7 C g2 u& y/ P) e
- g! v" B' W7 y; m/ T1 j' {( [' M
- public function query($where = [], $option = []) {1 Z) r9 H) O4 K& j
- $query = new Query($where, $option);' K5 {. k& ~( l# W% a" H3 l
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);1 Z e& S9 j9 @
; O; @4 t6 s1 g4 b- d& l4 r3 _% _' U- return json_encode($result);
7 d! L4 K8 C( N - }
' n5 d) f& B2 m+ @/ R! X
1 e) Q$ m! y O* j8 G9 }; z- public function count($where = []) {$ X/ P7 I& G5 w) h
- $command = new Command(['count' => $this->collection, 'query' => $where]);9 n' A) _" r5 _' v( q" y+ H
- $result = $this->mongodb->executeCommand($this->database, $command);
" G6 i2 S4 H3 e, K' o - $res = $result->toArray();; j' h+ o; n3 }# f% V' c. Q% y
- $count = 0;
) v- E; }$ \. P$ R - if ($res) {
* k. o1 s/ C$ ?( _2 w# `$ i+ f# v - $count = $res[0]->n;& l/ a0 D2 l; C! U; T
- }
) V# N% ^/ |8 Z - ( o2 q0 a3 i1 X; ?- R8 {; f2 O
- return $count;+ m9 B9 m+ j; o3 F) N
- }
2 _0 w4 x% h3 b
6 ^' n D8 `. @ p- public function update($where = [], $update = [], $upsert = false) {
/ s7 \- \ q- v6 H2 H - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
3 p d. L+ n+ \% }0 q* L% q% v - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
$ m# p% \3 ~$ L - B) a/ }' Q4 G( Y1 v4 A
- return $result->getModifiedCount();) c$ K! L2 @8 }3 y1 x
- }- g1 O# c" }& {3 B/ I
- . m6 L' ^: |5 T% J* U
- public function insert($data = []) {; Y( c0 c: w3 r1 I
- $this->bulk->insert($data);8 r, n" S3 Y8 ?/ ^' E
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);1 [0 u2 n& | @1 t7 a. d
: |" V _' ]- u) l3 p4 W2 p" N- return $result->getInsertedCount();
4 c% L! w, M2 P8 A - }
! I6 z* H$ f& T% w* U. i/ O - * H, z: c& o' @. O- t$ I/ c
- public function delete($where = [], $limit = 1) {
/ Y) t4 p0 _/ D' f6 }, u/ A - $this->bulk->delete($where, ['limit' => $limit]);4 C+ e: c; ^7 |5 a2 K1 Q
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
1 B0 z/ b; R! J' E - ^0 Z }! `1 g( ^
- return $result->getDeletedCount();
9 C4 d1 _/ y' n+ O( C" Q! f4 T4 b! t: q - }
T) v1 J m7 z1 n3 ^ - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原
# P1 x7 d. K0 C% G1 _6 M. o) L
- 新5 F# h' _8 Y" k* n/ |! b
2.新增- 原
2 A! X. I: K: @# s5 |* U
- $collention->insert($array, $options);
复制代码- 新2 R2 I" F2 r' e' x& ?3 H
- $resultOne = $collention->insertOne($array, $options);//单
. x2 v; n! K: J! A1 Z6 J. B4 g; l# w - $lastId = $resultOne->getInsertedId();
/ F3 R, \, q" K- f ` - $resultMany = $collention->insertMany($array, $options);//多
s# q, `! J4 s/ y0 {# F7 ^: s - $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [1 P. F* ] s; ?% X
- '$set' => $values
4 m/ R7 n, Q8 R' S, w- o- c - ,[( R7 ] }2 ], U- r, `) t% F# Q
- 'multiple' => true//多条,单条false5 _9 ^. P0 G8 I3 r! L- a
- ]);
复制代码- 新
3 O9 ?9 p' L+ |0 O$ C5 R
- $collection->updateOne(+ g' t8 r8 S1 k: e, m! N
- ['state' => 'ny'],& B. s% F- ]5 d I# J
- ['$set' => ['country' => 'us']]4 c2 t- s( e$ q! F! a
- );, s. n& Z0 k3 u; }: B( _; a0 U
- $updateResult = $collection->updateMany(
. m$ m& D$ v6 n+ c' u - ['state' => 'ny'],
; f6 d! j) g4 N% v; h7 H9 f - ['$set' => ['country' => 'us']]
8 y* d, B0 M$ @6 ~( u8 i: x - );8 I/ d+ |- P( @0 o5 z4 N
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [. D. U6 ~1 {- M; A @7 t: g
- 'name' => true//指定字段: Z/ g# n$ A) o. x- J
- ]);
0 X1 z0 e9 _9 q+ t4 N; ?3 m - $cursor->skip(5);
4 r( W d# ^7 O. u4 n7 E - $cursor->limit(5);" Y8 m" k3 c& y# j
- $cursor->sort([
" W; U7 y" v4 C- | - 'time' => -1, A% N' g3 f0 U7 d3 s
- ]);
复制代码- 新
2 O" Y0 F% b9 |( Q1 _2 O. |# V
- $cursor = $collection->find($condition, [
) g6 _5 [9 j5 \ - 'skip' => 5,7 Z5 k; k1 l& w0 Z' O0 J
- 'limit' => 5,; u4 e' x3 |, x. B$ U# P1 J
- 'sort' => [/ H: x3 l3 f% R1 ?# i
- 'time' => -1
$ e) n$ g% O; f: m& _) F/ T - ],//排序
]2 A0 l0 m' S: \% \& F T - 'projection' => [. ]/ H3 f! m" _( U2 N1 ?6 |; Z9 f
- 'name' => 1//指定字段# E" s5 ?9 i4 l" R# g+ W
- ]
3 q ^9 ]+ k5 x* u$ C Y1 k - ]);
复制代码 5.删除- 原
9 y. j% k9 B9 F: R5 N0 N$ a0 \1 f: K& F
- $collention->remove($condition, [
$ [! @; E$ @( |" b% z! ~6 c - 'justOne' => false//删单条
2 S4 S3 R: G. f6 \6 Y+ n1 M - ]);
/ W" G+ m! r$ {" w# D - $collention->remove([]);//删所有
复制代码- 新
4 M' P1 k, J) o* x% U! |
- $result = $collention->deleteOne($condition, $options);
* V f4 i4 u4 q. e - $collention->deleteMany($condition, $options);+ T. X' |& [% j0 d( z( v
- s- J9 ]3 |) b
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([) e& `" X5 E" z, N/ x
- '_id' => $tableName//我在自增表中用其它的表名作主键
, |; W# J3 c1 g' R+ t' f - ], [
5 r' l2 @: G1 b' J1 ]1 ~ - '$inc' => ['id' => 1]//自增9 H: ~% }' Y2 {, p! P/ R
- ], [
9 c& a7 J, h9 i7 w# N: r' i s" M - '_id' => 0
" K& ^0 k' |0 B6 p2 {3 g7 m - ], [+ J2 \' ?5 ? t6 t+ L# |4 i- X" V
- 'new' => 1//返回修改后的结果,默认是修改前的0 ^1 v/ a# z4 C2 T, a' g Q
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([ n* {. U8 U5 a( `: y
- '_id' => $tableName
$ I, ^* z/ {. Z; B C6 a - ], [
+ z0 n' Y V/ o* n. N0 e - '$inc' => ['id' => 1]& t( Z# e2 J9 ~) E, ~
- ], [+ H0 V) g7 g5 d/ ^$ x; Y; w) L
- 'projection' => ['id' => 1],
1 U: x% Y( L# w b* A$ D - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
1 w+ t* m& Z6 u8 r - ]);
复制代码 / |, z6 l0 W) X/ t! ~: G
0 \3 y1 E( Y/ _% V9 t
|