|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
( S, I3 z1 F( t3 f" t1 z9 d - 9 X {8 T1 o9 J% Y* J
- use MongoDB\Driver\Manager;
, {4 M/ s5 x6 g2 ]3 A - use MongoDB\Driver\BulkWrite;
" @: Z p* L/ k/ y! N2 c, A - use MongoDB\Driver\WriteConcern;/ Z0 ?. m& J& N, n8 H
- use MongoDB\Driver\Query;
" ] s+ n2 _' o( O3 w' {4 T - use MongoDB\Driver\Command;
0 k4 W( ]- Q+ }4 f# }" v( g
2 Y) J$ j, c! e# e( k- class MongoDb {
2 G N# L! t I j
% M6 ] l+ h# ], K) Z1 K4 M- protected $mongodb;9 P0 [7 k4 U) D2 D7 h1 `: p* I% \
- protected $database;
5 r9 b% v" N( w+ U& L; w - protected $collection;4 m z0 k) Y d) ]* `8 d
- protected $bulk;) _! F+ a9 m& v o5 C {5 v: N
- protected $writeConcern;
/ W: l4 F5 a& z( t& M; x - protected $defaultConfig
, b) c8 Z0 z% E/ F- Z5 Q1 D% D$ i - = [) ^0 |9 n( {! e( N* F' |
- 'hostname' => 'localhost',. N% j" [0 W* G+ D4 P
- 'port' => '27017',
/ n v7 N5 w6 h7 l) X* S - 'username' => '',
2 h, R: i* B6 W' q/ i1 N - 'password' => '',
3 ?/ L# F& Q: _9 }7 j - 'database' => 'test'6 l! k* k1 u3 u1 z
- ];
. B* x2 E4 `+ t9 |( @% G; K" H: y) } - 2 K" v+ H# F; e/ \
- public function __construct($config) {* t6 S! U. V7 n4 q- C# q( z/ J
- $config = array_merge($this->defaultConfig, $config);/ b# l+ O3 p$ y: U$ |( L5 `
- $mongoServer = "mongodb://";
8 ?$ X6 c) @7 s* \& k5 @( Z - if ($config['username']) {1 z+ Q+ E3 R5 T
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';: G" ~2 q& B3 H* l- H$ X% T( a$ W4 }
- } H+ M9 F+ b, J0 a
- $mongoServer .= $config['hostname'];
2 c% @! f1 o* e+ Z" H - if ($config['port']) {" p+ ]9 c( _2 t) X. j
- $mongoServer .= ':' . $config['port'];8 e1 h( ? x! W/ f
- }! c3 {0 g& y. @* V
- $mongoServer .= '/' . $config['database'];7 _4 ~: Y6 K% G
- , d; [( _7 v& t4 }
- $this->mongodb = new Manager($mongoServer);. ]9 t! a/ a( w5 s( r- ?9 q: `9 H
- $this->database = $config['database'];
& I' L" S8 x2 _! Z: ~1 B f }/ E - $this->collection = $config['collection'];9 }2 [/ \+ V# V: t$ N5 A& D% g* L
- $this->bulk = new BulkWrite();
3 O* Z* X7 k) G. S - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);, W, U$ q5 {5 F& E% }) D% G
- }
: {1 o' @% r B" C - / m) n; [) N( I$ [3 H
- public function query($where = [], $option = []) {
! N4 z0 b+ g* F- R$ ?) X- J - $query = new Query($where, $option);0 s4 g: Z+ I; W" g
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
* r6 \7 A( m" ], j8 F3 J" s) i - % b: o! a' v/ f& e
- return json_encode($result);0 _" \7 C' m8 ?4 u# B4 l
- }4 d2 g j+ `2 L3 n6 n4 O' q
- o; o, f7 [. R- public function count($where = []) {- s2 b B4 s% V' n! e9 Q0 W0 F/ i
- $command = new Command(['count' => $this->collection, 'query' => $where]);. r8 g3 P* T. m3 `5 o8 L
- $result = $this->mongodb->executeCommand($this->database, $command);
3 ^) D6 C5 l1 r a& p; i - $res = $result->toArray();$ z" |" s5 t8 @* c$ {
- $count = 0;$ r* @7 b3 `3 H- Q) j* m# }# ~3 \
- if ($res) {8 P6 q& c' w- i, s8 w
- $count = $res[0]->n;8 R. N* w8 F O0 v G
- }. d; o, N7 d/ Z; J8 Q9 X* H P6 E
- 3 u$ E. g) ?; V4 ]! b9 f; Z
- return $count;/ ^3 [7 R0 J' w J5 M
- }
% x- l6 Q/ [) `' K% z# z9 o9 @, C5 T8 \ - ) `+ U3 A! ^! {! ~) u
- public function update($where = [], $update = [], $upsert = false) {
% q/ i! ]( f/ p4 [& g# Q - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);" s! d4 s* [3 l F
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);, p: y0 I, A3 G& K2 p, e
- ! b6 t8 l; L7 |" G- J
- return $result->getModifiedCount();1 u: h. {, X" q2 A. h, u; D, h
- }
2 G4 Y* i) t, \$ {
- j# w. |' v- B) Y- public function insert($data = []) {
8 t4 w' `0 e! Q. r - $this->bulk->insert($data);
+ M; O( ` F. g3 ~$ a' c - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);, n& C/ v# F" d8 p6 S+ Y- J
- / H6 v$ G' g8 \: s6 q5 w5 d! B
- return $result->getInsertedCount();3 x& Y f J( F" Y1 G
- }; C/ F/ O* N1 { ]
- ) o7 t) Y! d' K+ k2 O/ N1 R
- public function delete($where = [], $limit = 1) {
6 r: ^+ o9 v! m; D- c0 K3 V% ` - $this->bulk->delete($where, ['limit' => $limit]);2 Q e& K- S+ P- b; m) @: Q; A
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
' V# |+ ?2 _4 @) `. s - 4 o5 x+ G* e6 b+ Q# f+ p% X: w
- return $result->getDeletedCount();) p5 D% r; _0 z0 J/ h
- }9 m% d" t5 _! D' ^2 K, y
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 新
) G; y! H. ^+ k" W0 I) G 2.新增- $collention->insert($array, $options);
复制代码- 新
: {% Z) k* C0 l# c8 f+ j
- $resultOne = $collention->insertOne($array, $options);//单6 @$ o2 Q+ i F8 X T# s, \ K
- $lastId = $resultOne->getInsertedId();
6 _4 t1 s& L Y - $resultMany = $collention->insertMany($array, $options);//多2 _9 w: ^# z+ G4 Y' H; C' B
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [/ u1 |- }# N, C
- '$set' => $values
1 h% B7 ^4 I* R' [6 r - ,[& e5 K8 `; \1 ^+ T* [
- 'multiple' => true//多条,单条false
& b; A) f4 h0 e' x Z( x' x0 l2 l - ]);
复制代码- $collection->updateOne(
) l# U7 ?' q; Q* T - ['state' => 'ny'],% @ @5 \6 m. q! w
- ['$set' => ['country' => 'us']]
4 y; {% f7 A9 {! j! S ~* x - );, v+ U- D, h0 j% S o& }$ n, [
- $updateResult = $collection->updateMany(
" Y3 a, M8 ]2 @- U& R, E6 e - ['state' => 'ny'],4 }6 g6 }) s3 @5 I- `. Q4 C* v
- ['$set' => ['country' => 'us']]+ Y% [0 `/ R3 V2 m! ^
- );% l# ~8 d4 l! }; w+ F! B
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
4 `/ P. Q* T( u' k3 V0 ^1 o4 B - 'name' => true//指定字段+ U5 J* H: [9 |3 y2 t0 k4 i2 V/ S
- ]);
; D& y* L. q8 O& ^$ F% y9 C( d - $cursor->skip(5);
6 G: l+ a2 p& K - $cursor->limit(5);
/ |5 E! r+ L. ?9 W, F - $cursor->sort([
/ t4 P9 [4 C! M - 'time' => -1, H, c" t$ s o0 z* ]
- ]);
复制代码- $cursor = $collection->find($condition, [
7 D- r3 @ Z. y5 g - 'skip' => 5,/ Q6 j) ?8 P3 S' g
- 'limit' => 5,* E& s: ?' u! @# i8 d
- 'sort' => [8 V% A4 R$ y1 V9 k5 U u
- 'time' => -1
6 O# P% v0 t2 p, M7 L# ]! K - ],//排序# \9 l- b% Z' X# A, P3 N' S9 l
- 'projection' => [
2 N; ? d5 Y" L' m" w' {8 S - 'name' => 1//指定字段
1 [, d# Y3 z( r2 o; t! `7 m/ A - ]
4 J* c5 a. L$ Z) d - ]);
复制代码 5.删除- $collention->remove($condition, [: p8 A: H. _% K& w
- 'justOne' => false//删单条
$ P* Z+ x, y: J0 s - ]);
; J. l) ~9 k7 O" {2 E - $collention->remove([]);//删所有
复制代码- 新
) m9 S6 z6 c" g* z5 u5 t F" L
- $result = $collention->deleteOne($condition, $options);
+ s8 B- D4 V. Z; R# t - $collention->deleteMany($condition, $options);* f, w9 s- L% s9 R# m3 E
- # q0 h# c$ [: W# _ q! i# c5 B( Y
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
& t: G/ j( I8 B9 y6 J9 C/ v* a* ? - '_id' => $tableName//我在自增表中用其它的表名作主键
1 G$ k# K |8 Z9 z- D& d( A. { - ], [# s& d- f- r% E
- '$inc' => ['id' => 1]//自增
! f2 y4 S6 G4 j5 Q - ], [8 X2 n6 O% _+ Q; a: x, N
- '_id' => 0
. M+ d. W- A7 ~: h& C! @ - ], [; Q& A" t$ e! q3 \3 ~3 q
- 'new' => 1//返回修改后的结果,默认是修改前的
7 I& f' d$ B' h1 P; H; J0 R# W1 ` - ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([
7 j5 [* `, v; i/ @: @& I! K - '_id' => $tableName* Z& M% k6 ?6 E1 W2 X' _
- ], [
- @# I4 I' G' I, q) m3 b2 Q - '$inc' => ['id' => 1]
; _, E" Q" S% }- i" V6 P. N - ], [
7 u5 h7 d9 B& k# ^, H! d. y - 'projection' => ['id' => 1],+ f9 n1 O9 Y, t" M4 o( H
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
' B: ~0 t; C& N f3 | N9 k - ]);
复制代码 4 `) y4 O b/ u" [3 A
2 w8 w( |9 }' P: M1 K
|