|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
& E& c: i% l+ {) e1 k - 3 ~2 u. B& D5 O! n
- use MongoDB\Driver\Manager;2 K( E7 `5 `0 h/ V* l
- use MongoDB\Driver\BulkWrite;7 O7 b3 `( Z/ P3 E) e! m0 q
- use MongoDB\Driver\WriteConcern;( @' h9 l& a& [8 p. C% P
- use MongoDB\Driver\Query;
' q1 g' c6 E; T7 x( G - use MongoDB\Driver\Command;
# ~) A; @2 x2 x% O' o* g - 7 A! ^" ]2 O6 R0 m1 \, t
- class MongoDb {0 j9 Z$ n2 _& y! R- r
# u# R( T$ A( ]% V* T- protected $mongodb;
. j7 I4 p+ u* ^; H. m0 a - protected $database;
/ _) v* f( F% ] - protected $collection;$ ?0 b1 M5 d5 I! U+ G5 u
- protected $bulk;, G$ s& F9 Y- I; t1 A/ @2 a
- protected $writeConcern;
& \4 E$ c4 x8 ]* o4 L& m, { - protected $defaultConfig% c O( `2 b4 y. L
- = [& [4 @3 h1 b4 a* r; x& q
- 'hostname' => 'localhost',
% d. c/ f% d! i- ` - 'port' => '27017',: s6 ?0 P0 C( j8 b# h
- 'username' => '',
* N/ Q7 Z; E4 Y. D( E. ]% ]. ] - 'password' => '',# P" C6 c+ ?1 Z
- 'database' => 'test'$ Y1 x: X) [. S, m+ p% k8 p
- ];; ~4 }8 r }/ P; N- a
- * O2 O) b9 ]- x# D0 k# t7 Z& X
- public function __construct($config) {6 ~. B2 ?* ?4 A
- $config = array_merge($this->defaultConfig, $config);9 s; K* B8 [/ D7 U/ K- N1 @
- $mongoServer = "mongodb://";
' `# d/ v+ a. ~4 a4 w/ g - if ($config['username']) {0 |* d1 A1 a( w" A5 W' e
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
2 ^, l. ~ `% e5 x - }
4 [. w/ r) x* ?3 e; J8 ~$ B n - $mongoServer .= $config['hostname'];- ]$ s# [$ U: J2 J# H) Z
- if ($config['port']) {: J# i8 j6 T. e: b
- $mongoServer .= ':' . $config['port'];
* o5 |- N! r* [/ B! y, w3 J - }
3 J1 s) ^+ l. G/ r- f - $mongoServer .= '/' . $config['database'];
1 R$ z. U& n/ R+ s - {5 I3 h F9 G/ q$ T4 j
- $this->mongodb = new Manager($mongoServer);
( e f$ M. U2 Y& ]1 v6 a) _ - $this->database = $config['database'];
) A& d. {$ M' I# p s7 G' Z8 ` - $this->collection = $config['collection'];
% E$ y- d$ O" W! Y/ j/ T - $this->bulk = new BulkWrite();+ o; n `- J/ P* X L/ O. f
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
' D7 B: Y0 j, ]& v5 ^2 f- N6 M - }
6 _+ G2 E0 Y, [ ^0 y
5 i2 C1 Z) f+ S( M R- public function query($where = [], $option = []) {
$ [/ y1 x% K. ?: a: G7 [- D; E - $query = new Query($where, $option);
# [9 [0 Z+ \6 U# @5 t - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);% s/ j7 f& _1 V, u9 N
- ; `. i; x! J- Z
- return json_encode($result);( t0 l! n" |% x5 p2 d0 O
- }
! N3 c: z! c" t4 f - * d {1 I% S8 l7 V1 x
- public function count($where = []) {
5 `4 o+ m7 ^( Q7 M& b - $command = new Command(['count' => $this->collection, 'query' => $where]);2 { N9 C+ }* H
- $result = $this->mongodb->executeCommand($this->database, $command);
- o% |# d9 f- V) c - $res = $result->toArray();9 B; ?4 L$ Z) `% \- N1 H8 N. u1 w
- $count = 0;7 J7 {2 e# N G" o0 _1 p* V
- if ($res) {
8 @/ ?7 [* z0 J3 n' x/ E - $count = $res[0]->n;+ z! B+ B! U8 W
- }+ F |0 H& P/ m I" n3 n
7 I& h. q$ a( i& Z5 O( B: E- return $count;
- x! X6 E$ ~+ g! T- @; C - }
! V- o* S" a' S7 X% C( z/ M% Q5 n
2 B8 | R. C/ }0 s: @, n7 D- public function update($where = [], $update = [], $upsert = false) {: l( t$ `0 {( R1 c5 J' z0 {
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
) i1 d- d8 e3 A& x7 ~6 r( }0 N A - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);# p* p' \- r2 G( h
" m7 a% \ q# b8 X: x$ ?- return $result->getModifiedCount();
, {; |3 i0 E% t - }
- J' L6 [" f" U/ H* A - 9 {: |6 {. U! _& M8 u
- public function insert($data = []) {2 n4 S6 F- g" z3 F3 s/ V
- $this->bulk->insert($data);
, v. b, P. x6 {7 ] - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
; [2 W* D" O9 S/ l: @3 ^) {
% P g/ V% K! E3 T' U8 ^1 y- return $result->getInsertedCount();( P2 W9 f& E |7 ]8 e3 N5 ^( y
- }
2 P7 K( S8 D/ n - + \, f+ @0 \: ]0 P& c
- public function delete($where = [], $limit = 1) {
* s" _1 ]) S A( V - $this->bulk->delete($where, ['limit' => $limit]);
$ ~3 k8 C" c: l4 v - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);0 I" p, Q& Z! ^$ F5 h
2 E+ P% W3 Z0 d, @- return $result->getDeletedCount();+ ^* ~& l8 E+ ?; g0 p
- }
" T8 w6 k9 M) b0 Y - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原/ {4 L9 ] l! n" O) U5 x, T, D0 M
2.新增- 原8 W! ]5 h) H f, x# t4 D% d% \
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
- u& w, A' z" W& B( ^* j4 B$ o$ { - $lastId = $resultOne->getInsertedId();& ?3 ?0 J2 l$ E) ?) N1 ?2 p, |
- $resultMany = $collention->insertMany($array, $options);//多6 Q( p( {7 J% K/ d' d0 U" ^0 n: ^
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原$ O+ J- R1 L1 r3 V! a1 I3 N5 V! m
- $collention->update($condition, [6 B. V$ c: K1 g+ C5 q1 L
- '$set' => $values+ f2 s5 s$ p6 e& p. J" @
- ,[, ~+ m# e! Z& T& x7 Q: c2 r
- 'multiple' => true//多条,单条false! x; ^( n, B$ \; H" Y; r
- ]);
复制代码- $collection->updateOne(
% w8 b6 f! H8 W" D- G - ['state' => 'ny'],
" [# W: L8 g4 Q) x& I* Z - ['$set' => ['country' => 'us']]
1 f3 M4 h$ a- J' _0 l6 D$ h! w - );
- Q0 |, l3 m8 }- }5 t. T w - $updateResult = $collection->updateMany(
6 b: j4 f R" H) B0 m - ['state' => 'ny'],
2 ^3 |- a4 c0 D9 ^0 K - ['$set' => ['country' => 'us']]& U( A, c, E: o: A, b
- );
( `- ~! X6 v/ Y - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原( ~( M; p1 r6 d# {2 Z% Z
- $cursor = $collection->find($condition, [+ b0 Z2 P, L) X: `( \) g
- 'name' => true//指定字段
/ \0 J* c# _! t# ~9 c - ]);
, N* W2 y. J9 b - $cursor->skip(5);) S9 y2 B Q) ]
- $cursor->limit(5);
& ?; t7 \6 U. u7 f1 o2 L - $cursor->sort([ `0 j0 L1 O# ?0 X
- 'time' => -12 r2 n0 x e; w$ q
- ]);
复制代码- $cursor = $collection->find($condition, [! h8 f' b+ ?7 J& d' _0 n
- 'skip' => 5,! u2 |- A$ K" O* V9 c; l' t
- 'limit' => 5,
) ]0 A$ E8 E5 J$ @ - 'sort' => [
4 |- D1 \+ p! H' p# P* T6 o - 'time' => -1
2 L2 W/ ^$ e9 i# ?- U4 K V - ],//排序8 F6 F7 h( l- C8 M; ~7 H% M( X" ]
- 'projection' => [/ M! h8 [! @2 `
- 'name' => 1//指定字段. Y; p6 Q& V$ f$ {0 n/ ^ [
- ]) K `2 J+ o5 r4 s$ W+ S* O4 t
- ]);
复制代码 5.删除- $collention->remove($condition, [
2 K; L" \/ e5 L* {5 b9 Q - 'justOne' => false//删单条
" {& x& M7 e2 E- M2 b$ p U# N( W, X. | - ]);& s5 E8 M% X3 b% e/ ?, R R
- $collention->remove([]);//删所有
复制代码- 新
% y) z& E3 f; |( Z# |6 Q8 }" X
- $result = $collention->deleteOne($condition, $options);
2 g( U) N R9 A - $collention->deleteMany($condition, $options);) w0 B- K5 u9 H% p1 F- R8 N% Q
- , _: H2 f1 |3 I) i, i
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([! V1 `/ x5 [7 A' K* C
- '_id' => $tableName//我在自增表中用其它的表名作主键
+ F0 V" ]( H! R: n - ], [6 R) J6 t# G& l* b J' L6 h
- '$inc' => ['id' => 1]//自增3 o ~, j+ S0 G& ^ n
- ], [% I- M+ w- w1 a' z, b* S/ I! e) u6 i
- '_id' => 0
& o, Q5 `. B) @- c. t% \, j5 P - ], [/ z' ~. ^) `; N! L( {. H
- 'new' => 1//返回修改后的结果,默认是修改前的
# ?, p, R& M% M, R* v - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([ F! L' j; {/ P5 ?0 G& {* w
- '_id' => $tableName
& h8 L/ ^: @4 b7 G9 H! ? - ], [
# j& X0 Y8 `; n% [) [ - '$inc' => ['id' => 1]; @8 N- c5 S) [9 K. V# L' L
- ], [+ t0 `' Q6 E% w+ n @/ E
- 'projection' => ['id' => 1],
7 k* m! S# `) |( ~, \+ V' L8 K - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
V+ L. R9 I) s - ]);
复制代码 1 r) H% p9 f1 w% g4 Z+ [. ^/ c
( W! r( `* ?8 P [! v4 K) \7 [
|