|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php# R8 ^. ?0 d+ u, y, U4 q
- + Z% P5 ^) |% l. p" G; _- K
- use MongoDB\Driver\Manager;: ^$ v* q2 R! w5 L, v7 O: K! k5 s
- use MongoDB\Driver\BulkWrite;
/ |" G; e! m. K9 M2 D - use MongoDB\Driver\WriteConcern;
1 `3 T {, Q# L0 D: e- { L. g' n( o - use MongoDB\Driver\Query;8 p/ h# e& n( x2 N# {
- use MongoDB\Driver\Command;
9 @/ X- x! a% D6 x" y - , x6 G; a `1 W8 {2 ]' p1 K
- class MongoDb {
$ P$ D9 ]+ ]9 c1 K' b
( E) {5 L/ s) P- protected $mongodb;
4 v* M' ~5 `! J! M! q9 d - protected $database;
, z0 f( J, ^4 ?: j6 j- \# ^ - protected $collection;% Z0 B0 A5 a+ h& q
- protected $bulk;
% {' R5 @( p0 Y( k6 D9 h: Z. j9 A - protected $writeConcern;, |6 _# |8 D; m o; h8 c
- protected $defaultConfig
8 T2 }! x% w3 @+ l# d6 ?0 s' H - = [
) o7 Y3 z0 I ~+ T - 'hostname' => 'localhost',+ R) i- D* W! v5 S+ d3 P/ r
- 'port' => '27017',+ [& C% P9 @$ E# h9 b0 A3 ?
- 'username' => '',1 J" {1 A) ?6 k) ]* A( ^
- 'password' => '',( E) P- n N& y
- 'database' => 'test') r! p' D6 j4 i6 b( N
- ];
5 c! K% l) _6 ]4 Y# X9 ~+ H. {5 {! R
9 E P1 _" `5 J- public function __construct($config) {* H6 T+ R8 q( l" [% Z, X( j- _; i
- $config = array_merge($this->defaultConfig, $config);
3 }- A n. h4 a; p - $mongoServer = "mongodb://";9 X9 P$ O2 n0 `" E; _9 r1 w( n
- if ($config['username']) {' ]1 i4 Y" k8 o/ y( \2 H
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
5 \0 S! j/ M- e$ t* V) C7 m - }
" n8 v- p; W3 A0 e - $mongoServer .= $config['hostname'];4 G' l- \' v+ C$ M2 j/ `4 T
- if ($config['port']) {0 P) V3 r2 A! @( h- \' y( I, X
- $mongoServer .= ':' . $config['port'];
) p+ \! J- D$ {7 P - }, k0 i! P- f( ^9 }
- $mongoServer .= '/' . $config['database'];
, p' ?3 b% I0 V3 v: J
$ [+ @, j3 g3 M$ V# X- $this->mongodb = new Manager($mongoServer);
x) W$ f5 O/ @) ?3 u/ a2 f - $this->database = $config['database'];
5 c) o3 q2 n- ^9 t: o. r4 e( N - $this->collection = $config['collection'];% C8 t9 s! m0 c' X; @1 ]1 ~5 s0 s
- $this->bulk = new BulkWrite();, i* k% g9 S# }- v
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
) ^+ w9 U4 Y: a6 w! q - }' `3 _; ~+ I% n: I' s
- / S- ?" _9 G- I3 v
- public function query($where = [], $option = []) {( P( V& R; O- _) h2 v- v# b
- $query = new Query($where, $option);
9 b& G' e9 Q: a$ U' U& k6 R8 m - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);3 M9 Z% b W3 i+ Q# T
- 9 d" K" U( t" f
- return json_encode($result);! X/ `# c" O+ T5 v4 Q( m
- }3 z' _. Y- G: Z1 J6 a) P3 ?" t
- 0 l8 c" {- c8 E9 q! J% C
- public function count($where = []) {; p% B7 X/ W2 W; y- L% v. v3 b8 S
- $command = new Command(['count' => $this->collection, 'query' => $where]);
6 o2 U. w. y `4 N" v - $result = $this->mongodb->executeCommand($this->database, $command);+ _1 P; F5 f5 A) l& V1 p
- $res = $result->toArray();4 W0 q# j5 e+ Z+ h* Y: \
- $count = 0;4 l4 d6 {' w X. ^& @' a) Q
- if ($res) {5 I4 A6 j) |6 ^. w& p, ^
- $count = $res[0]->n;& H" B9 B5 A8 Q5 K Z' h0 x
- }
' i, d+ \1 O, n+ a. _) V6 ^ - 9 e; @, T4 {7 M& o, E2 ~1 W
- return $count;
- A; y) ^4 M* Y5 T. B6 I - }
$ B1 e/ M, Z( |2 C
4 t+ g" o a& d* u2 j- public function update($where = [], $update = [], $upsert = false) {
6 [8 A2 `5 ^" F! e, a l; q - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
" ^1 M4 Z- N$ U5 M6 o7 T - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);. P5 R- d! T9 ?' J% X. v# Z0 q
: m' r! r1 @# _ `3 ^- return $result->getModifiedCount();
7 ?& F" j1 f* y6 M - }* H3 O4 m: K% X6 ?: c2 a' B
2 a! N$ o3 b7 k0 y- public function insert($data = []) {
0 c0 g# W3 Q0 H. | - $this->bulk->insert($data);! `2 z3 m; b, J- M+ W! A
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
8 v2 b+ r* L; Q/ X* ?
8 H9 k8 A4 \+ S- return $result->getInsertedCount();
" \/ l6 V3 Q0 `* I' X+ \9 u - }9 o, h, c/ B* W9 x
- ; s3 ?* |' H( w
- public function delete($where = [], $limit = 1) {* w2 _% J1 |2 M" [8 x
- $this->bulk->delete($where, ['limit' => $limit]);: j. e( @4 A* M: f, b6 o9 _3 j
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);! o8 `! _' Z2 V8 z4 R, M) j
( A* L. r9 r5 y- F) N% C- return $result->getDeletedCount();, s& H$ }: e; y, l$ H2 T+ i; D
- }" \2 a" u6 `4 ?
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单3 A `* j* G! P. n5 | u m0 r& O
- $lastId = $resultOne->getInsertedId();7 l$ Y5 i- J% b
- $resultMany = $collention->insertMany($array, $options);//多
3 }# y% @$ U! ^ h# P - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原- x# U* ?& Q3 x& n) j' I
- $collention->update($condition, [8 w3 g3 t" N$ ~ T, w e
- '$set' => $values1 P5 \# Z8 f7 o+ d9 q; K% J
- ,[( x+ R9 h/ Q* y$ ^) `
- 'multiple' => true//多条,单条false, t) T, n3 Y; V' Z/ m4 L
- ]);
复制代码- $collection->updateOne(
9 m3 ?' o. `' ? - ['state' => 'ny'],% n- W; O! _5 b
- ['$set' => ['country' => 'us']]+ A) q3 B* H! M3 M
- );
3 b: O3 y9 W+ d& w$ d - $updateResult = $collection->updateMany(
" O: N# I) a% N A0 f; | - ['state' => 'ny'],# |8 Z" I4 R/ j7 c& C4 x* v" ^* z
- ['$set' => ['country' => 'us']]
4 b" `2 t+ Q- }. R: g - );
& q) X* C; x0 \+ h& o6 o, v* P - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
2 r( l9 j1 R, }1 R% \ - 'name' => true//指定字段' ~* w- s% Z; F" D
- ]);
7 h( z9 r( h2 z% o& Y - $cursor->skip(5);9 K; L1 G9 \0 ^$ Y" U$ o
- $cursor->limit(5);9 d- s' E$ _, O0 ~3 ^. R
- $cursor->sort([
g. L( \9 h& b, K! A - 'time' => -1; g& U& l3 U f% a. k+ K
- ]);
复制代码- 新! ~6 X) x B. _ F% O% C4 k5 e% z
- $cursor = $collection->find($condition, [2 }; A+ p4 J1 M
- 'skip' => 5,+ A% i0 \" o; H. p; q4 w' `" c
- 'limit' => 5, `* t( d/ b; F
- 'sort' => [
& G! }" u6 c6 x& ~) t2 C/ P W - 'time' => -1
) w$ i( A/ K" t - ],//排序
" c' u4 v3 R' s9 x$ f& m/ K - 'projection' => [
( t" N9 ~9 b5 x - 'name' => 1//指定字段
5 r0 \& u/ E. c) g o' q - ]
2 ]9 C2 p: O6 C, c - ]);
复制代码 5.删除- 原
6 N2 R' c: h4 \, X1 Z0 \$ Q
- $collention->remove($condition, [ Y. x- o2 z/ r L; o2 {. k. S
- 'justOne' => false//删单条) t6 t4 A) w. }' }( j7 l" `
- ]);
+ P4 H8 w' | N. z8 m$ Z - $collention->remove([]);//删所有
复制代码- 新- y! |* S6 I: d9 X; }. }: I& t
- $result = $collention->deleteOne($condition, $options);) j8 A, P: {, L8 w& I& d5 u
- $collention->deleteMany($condition, $options);) B5 H4 `( }1 U* u& ]8 y
- ( Y: m' s+ {1 b3 f
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
* c/ I& j: q4 E0 G+ M - '_id' => $tableName//我在自增表中用其它的表名作主键/ m& R- b2 o9 r5 ^ g* c! ~
- ], [- n% O( }& l1 ]. h( P& s
- '$inc' => ['id' => 1]//自增2 n' y9 }6 T9 `5 G) T, C
- ], [, _+ L N; j7 `+ f3 p
- '_id' => 0
! G8 ~: s5 c5 M$ _& p - ], [
1 F: L5 R& @+ \. o% l1 w6 N - 'new' => 1//返回修改后的结果,默认是修改前的% g2 b; f/ K |3 }' O3 o- H
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
7 D* n6 R3 a( H. r - '_id' => $tableName* g5 B! X, x. u5 z9 X! \! K1 U
- ], [+ l# n$ A: s8 S6 d
- '$inc' => ['id' => 1]
- Y% u; n! Y. ~ H - ], [
% X, V0 M2 z+ }: m' _' ~/ Y - 'projection' => ['id' => 1]," u+ U; \* C& g7 S/ ?
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER% S* [2 F) [ s" ^( D
- ]);
复制代码 ( i1 h# E( s% D
g/ G' }/ x& S
|