|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php) j1 ]1 l4 _$ Y# i" L
3 \% P' T1 L* J+ F- use MongoDB\Driver\Manager;. [* F2 B A8 V" a
- use MongoDB\Driver\BulkWrite;0 f y, ]& j( x8 Z5 g. h. l8 _
- use MongoDB\Driver\WriteConcern;
& v( K( W% v; m* T2 r! O, J. c - use MongoDB\Driver\Query;6 D/ n2 {: E4 }8 }, [6 G: C! E
- use MongoDB\Driver\Command;
$ n, c1 E9 @6 b7 u4 s. V4 u
% R% Q8 g, x; s: ^$ |( U+ f- class MongoDb {6 q; }7 X& l9 S- l
4 i% S* H: [, S) C- protected $mongodb;
2 S3 t9 i$ w) t) d - protected $database;' G$ Z \/ [% k) {3 I: n4 n5 I
- protected $collection; b3 X" V( ~ A! a
- protected $bulk;; m6 p1 M: ~6 M/ x" l `9 a
- protected $writeConcern;
( H7 S t- n6 N4 Z& W7 @: E - protected $defaultConfig8 X! g" G4 E- S. f. u
- = [2 u# S. U: }, c
- 'hostname' => 'localhost',
8 x- ]1 P/ e9 j0 e2 @ q& g - 'port' => '27017',; h. F& }8 e8 s# n2 C
- 'username' => '',
$ k+ I- j" I0 }# T. {6 P+ h - 'password' => '',
' j% K4 L- h z$ q - 'database' => 'test'
7 d" C( F. L% u* T6 {8 K - ];) ?6 a- h# | ]( m. t4 o, v
- 2 v2 O4 |7 n+ u- b- z5 ]' v
- public function __construct($config) {. J! ^$ F3 K" f4 V1 U
- $config = array_merge($this->defaultConfig, $config);
! Y$ x4 a) b- q( S( n1 C) B - $mongoServer = "mongodb://";/ L1 [. q% o: C+ X! u+ w
- if ($config['username']) {5 Y( s# `* E. h. h/ I3 @
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';7 F8 ]. D* f+ `2 r) D" W
- }
4 y% {- ?9 @9 H/ Q6 ]$ b `* J - $mongoServer .= $config['hostname'];% @' c# ]4 {4 G9 A# a) v, L
- if ($config['port']) {9 j' t: ?! J" ]" E1 Q; _
- $mongoServer .= ':' . $config['port'];+ n: C0 \$ _; G& D
- }6 c+ p7 e& ^* t# v% K6 o9 S
- $mongoServer .= '/' . $config['database'];
4 U+ j. i9 z% G) k1 d* D
* y+ w# W9 Q' c6 @2 \; @9 @" p- P! P- $this->mongodb = new Manager($mongoServer);
# L! I2 }8 o" F1 A - $this->database = $config['database'];1 U8 Q- F" c9 f6 y3 }
- $this->collection = $config['collection'];6 h# K8 ^& q6 U8 _6 {
- $this->bulk = new BulkWrite();
. D% E% [% Q4 L( h" c$ y; @9 t - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
# y D' s/ z* ` - }" `' P' Z; N0 z3 K! p# Z0 g, m
- 9 V+ c% D; i" ]& Q
- public function query($where = [], $option = []) {+ V9 Z/ \ Z, X, o
- $query = new Query($where, $option);
4 V0 Z- N! X" B$ F0 R6 r' J" x0 b - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
; @0 F: |% U9 U6 E6 B9 u2 u - / f; P b. M/ I& k. a" B5 E
- return json_encode($result);/ ~0 F3 Z; c( {3 O6 u
- }4 p3 q* r- a( j: c# k
- ; j0 P" T! a4 z( b) m
- public function count($where = []) {
9 V- k+ h$ C4 ]4 j: y4 o - $command = new Command(['count' => $this->collection, 'query' => $where]);9 N* t0 ]! I+ u( p7 ]5 G" ~0 e
- $result = $this->mongodb->executeCommand($this->database, $command);( ~% B4 T, _: N, L/ o" j4 p
- $res = $result->toArray();; G7 Z* x; Y7 Z" s$ {5 J3 g
- $count = 0;6 B7 J; k) [7 L# W' u E/ V9 e) m: D# m
- if ($res) {( F3 [5 n+ K: g- T; Y
- $count = $res[0]->n;
* h, [% _( o# K7 |0 }" }& _: f - }/ @3 }, N) p2 Y( k( B
- P. I; ?6 _2 ~ [; M- return $count;
9 C+ C. ^4 c7 x. b% G - }6 }- X5 G! F! X. `0 G5 ?5 c
" U# c% H; A5 j6 @2 D6 T. @; O' V+ r+ X- I- public function update($where = [], $update = [], $upsert = false) {
6 }6 n" W! D t8 ] - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);% n0 Z9 {9 r# o9 k. L9 t
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
9 V( I* j, x4 H ]' a( j" Z - , c( y4 M4 J4 e( C& g
- return $result->getModifiedCount();
9 F: d3 l) s/ z) R# |5 C: T* t. S - }+ C3 r) T/ U. o2 p$ e
- ( g# z3 S% p. o5 }/ O: Z
- public function insert($data = []) {
7 z0 L" Z# ?: C' B5 r$ l, |6 p6 b, @ - $this->bulk->insert($data);7 T6 n# ?5 e( o/ L' r. X( z
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);) n/ w$ t4 c1 u# \4 Y1 X' W% D
- 8 u$ c; t% x% M- ~! S# p* C p
- return $result->getInsertedCount();: I; c3 a; u7 \+ B7 P: W/ t0 c2 G
- }8 D6 W: D; |* ? k9 v
: W% p: @+ N8 _" k# Q% j- public function delete($where = [], $limit = 1) {
3 Q% `! ]2 G; ~. [7 b! S2 e k9 l - $this->bulk->delete($where, ['limit' => $limit]);
1 y' T, `- _. | - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);9 ^ {4 p m# y3 o
- 8 j$ d2 \" L1 }& E" @, \
- return $result->getDeletedCount();
; X& B5 l! o5 q7 G1 ~- ]5 t* U3 @ - }* M7 f: F+ }; g% Y, ]
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 新
, d( S |) E( Z0 M1 b- W% s 2.新增- $collention->insert($array, $options);
复制代码- 新
% t8 d' R( b! A/ T" E6 {: U* H' X
- $resultOne = $collention->insertOne($array, $options);//单
4 Z& N3 w7 D1 C* r - $lastId = $resultOne->getInsertedId();
& B- O Q. b# X4 Z( J9 j - $resultMany = $collention->insertMany($array, $options);//多7 A( a' I w3 E, _% |
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [& t/ P' B3 u/ X
- '$set' => $values
9 o7 ]& B0 B: w- [' U - ,[5 H; P$ _0 C" v- Q
- 'multiple' => true//多条,单条false; S% Z9 r+ ~/ d& y
- ]);
复制代码- 新- N& D3 \9 R! x' p3 m! _
- $collection->updateOne(' s) x8 N5 R+ [/ N& M
- ['state' => 'ny'],
6 R3 o: V9 i& s2 g7 f - ['$set' => ['country' => 'us']]# n; c6 r. ~) S, Q
- );# I" [$ ]$ R; P
- $updateResult = $collection->updateMany(/ A* N3 y. x0 [1 r- Q
- ['state' => 'ny'],
" T6 F" q0 P# g1 ]/ B) ] - ['$set' => ['country' => 'us']]
, x0 S0 K' Y: g& j: x& ?# { - );( H i6 y. e6 [% {: `
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [8 F3 f6 B; w% q8 E2 ?- Y
- 'name' => true//指定字段: n9 e6 N Z. Z7 u5 w$ x
- ]);( [+ H+ n" c: G/ W: }& B: B
- $cursor->skip(5);7 F: o( K1 @5 B$ M" R: q. W! [
- $cursor->limit(5);& ?, R) d O0 f, J; o" E% p, a
- $cursor->sort([
5 O2 Q+ z3 d. ~% t$ @' q* y - 'time' => -1, P( j( i* @3 f" w" d
- ]);
复制代码- $cursor = $collection->find($condition, [" B: k! n' s* W% n7 p
- 'skip' => 5,. a9 v5 ^& }- A5 v
- 'limit' => 5,( O& _8 z- m: _3 ]. Y5 ?
- 'sort' => [
5 |7 J! g. c; n9 n - 'time' => -1
1 B b& ^: k4 D) O- _$ h$ C - ],//排序 Q6 ]* g: X- T2 d# ?
- 'projection' => [
6 v1 O8 D( W% o, K - 'name' => 1//指定字段
% |! ], X D) U! u - ]# ?$ u7 s8 V5 @- x" ?, P& c
- ]);
复制代码 5.删除- $collention->remove($condition, [5 T5 N/ F" u/ R# W" \2 X, ^
- 'justOne' => false//删单条
$ w% k. R' s+ u, S. ]( k - ]);8 L: Y. z% u8 X+ @: Y2 p, t
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options); B+ y$ \0 a1 g$ f9 I3 l
- $collention->deleteMany($condition, $options);: d9 O# y b7 ~8 r+ C& T
- 2 {- G( b* p0 N7 I: |
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
+ f9 t4 X0 A8 U' U8 }* C - '_id' => $tableName//我在自增表中用其它的表名作主键& T/ k' V( t$ Q S+ f; z
- ], [( [; l1 h3 ~& X
- '$inc' => ['id' => 1]//自增
$ r, d/ w2 ~, P% F% ? - ], [; T3 @8 ^. [' }- Z' x
- '_id' => 08 m) G( y# J' @2 y4 `
- ], [
1 p4 m$ N+ i A# w$ p% | - 'new' => 1//返回修改后的结果,默认是修改前的
% y: U9 O$ M0 c2 J3 F, S4 d* ^% N - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([& j+ H+ n5 Q5 w
- '_id' => $tableName5 y6 e0 ^. s) i0 }- L6 ^
- ], [
/ m/ U5 U: ~% b, H) G - '$inc' => ['id' => 1]
' }+ L) y" k* b - ], [
2 Z1 w- i' }6 j( r9 D, M" T' Y1 l6 Y - 'projection' => ['id' => 1],
7 ]3 }. S% K8 k" K - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER4 n1 A3 _% K9 f8 Z" G" L' C
- ]);
复制代码 : ?) q& R7 T: H7 g( u+ \8 e' @) h
5 z7 X$ w% ^+ x9 X. m T
|