使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php9 n4 u4 d. g$ G2 R! j, n9 _
/ C) g& X, j# o) u# N+ y- use MongoDB\Driver\Manager;2 W, z( o4 }: N _/ i" O
- use MongoDB\Driver\BulkWrite;
( Y F v. z& _ k7 M! _ - use MongoDB\Driver\WriteConcern;' Z9 o' a$ K4 @+ ]6 w0 K
- use MongoDB\Driver\Query;
; G4 `- a) w5 V9 b; z. S: \ - use MongoDB\Driver\Command;
9 a/ A' @$ O# S& \( t) e& `5 x
0 w( u7 L8 n7 S; I7 Z- class MongoDb {! V, @$ j5 T Z
8 i) E7 E# N9 L d3 @- protected $mongodb;) }" J, r, Y) z1 [% g+ U
- protected $database;+ ~% s, p( ~: U8 J b% s, m" l
- protected $collection;
/ n& F/ x( J3 r) J+ [) f' q - protected $bulk;6 F* B+ s8 g- j
- protected $writeConcern;0 b9 @1 Z3 w' q1 T, t+ Y! x! }% r
- protected $defaultConfig$ I# b7 a: i: U* o; c
- = [
: D2 O6 y3 [. e0 G% K - 'hostname' => 'localhost',2 q7 P, W% n% J! `: J
- 'port' => '27017',8 E9 s7 W r5 P8 V, [2 U% j0 c
- 'username' => '',! j: x. M1 x4 ?0 d) D( v
- 'password' => '',2 {6 b q( Q& W) E" S7 g
- 'database' => 'test'
% r! d, x* @ I5 S - ];- h& Y1 ?. w) F% I7 B
4 a4 {9 |( H7 W) V0 N- public function __construct($config) {5 s$ L# q; Q+ W; V
- $config = array_merge($this->defaultConfig, $config);
, L* c7 g/ ]( f o% |, H9 | @$ I - $mongoServer = "mongodb://";
! k" P! _. K, a6 d* M - if ($config['username']) {& _' Q5 D/ `/ g J9 |; U4 r: u- G
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
- L+ d) q/ B( j4 j2 \$ N( _ - }
# {" c8 Q8 X( k8 g/ f/ x - $mongoServer .= $config['hostname'];8 {8 y/ c9 h9 o+ [, N9 p4 k; `
- if ($config['port']) {0 j3 W" [+ I3 I( F
- $mongoServer .= ':' . $config['port'];
- b: U& k& h% R, R, E: V8 M3 _: Q - }
) [* B( d$ Z4 S+ j - $mongoServer .= '/' . $config['database'];
7 R$ r h! \, v - $ Z6 O0 ]* S( ^4 B
- $this->mongodb = new Manager($mongoServer);
' t5 n3 d# g e - $this->database = $config['database'];
% v3 n7 e6 M1 E6 F - $this->collection = $config['collection'];4 X# ^0 D. d; D1 o$ @- [
- $this->bulk = new BulkWrite();' U- Z6 S) c+ g6 k k. n* b) s
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);5 D" w. G- y2 i) Z& ^; X
- }
9 `" J# m6 g1 v6 s - - U n( @7 v: j0 {" J
- public function query($where = [], $option = []) {; i. N1 N I6 r5 j7 H
- $query = new Query($where, $option);
" V' F' I9 Y( q( @( r/ J& t2 P2 P* ` - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
7 p+ N& v& S: m
' J7 L: [9 O) [ W5 g6 l) |2 j- return json_encode($result);
) @' \% J' @/ }' ~* P% B - }
/ K9 o8 \3 Z! X; ] - 2 @5 _& Y2 R6 @
- public function count($where = []) {
: e7 | v7 X. u1 b, T' A - $command = new Command(['count' => $this->collection, 'query' => $where]);
9 V) \* K( }) o# d, D$ l& T - $result = $this->mongodb->executeCommand($this->database, $command);9 a8 O* ]0 Y( D' |* a' W) _% c0 J
- $res = $result->toArray();
4 `( |( J& H; m: @! W - $count = 0;
; i ^! {" L. z" r, ]# T - if ($res) {. m0 |2 B' K u0 g
- $count = $res[0]->n;+ s2 b* M" Q1 Q/ C) [' `* e
- }$ ^: Y- c! L! Y7 e/ E
' w) s( W) I/ K* }* H- return $count;
( Q) i* K! l( m/ W - } `+ M( o) P$ ^: ]8 u0 G
- 3 a3 z0 t7 m& k/ E2 E n) _
- public function update($where = [], $update = [], $upsert = false) {; B2 G' i5 S* N6 f5 b% U# I7 {3 |4 _8 T
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
4 n- S" f+ B4 G4 d; L - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);' \/ X$ E" ?! e8 {: h& X
- , H# H3 c P* }0 Y& D
- return $result->getModifiedCount();
/ T6 \* A0 e9 p/ y - }" V, S6 H0 M e% P9 t) J
- 0 `; z6 `6 ~: m9 J2 B
- public function insert($data = []) {
& [' t9 f" W+ U1 d, N8 l4 \ - $this->bulk->insert($data);+ f5 ?/ Y6 a+ S8 Z8 h
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);& P' c/ k6 Y* b; \
8 ?- |# h+ ~( o+ K- return $result->getInsertedCount();$ ^0 E3 M0 N; ?2 R7 X) l
- }3 B' W, `# W' B: x9 f' P6 K$ f
- # Z. |6 s% S N/ v8 x. i
- public function delete($where = [], $limit = 1) {
" J( H8 c. p, V2 N6 h5 N+ Z1 J3 s - $this->bulk->delete($where, ['limit' => $limit]);
# `6 i( Y) y. W% V0 Z( C - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern); I/ c) O8 M' T5 R+ u) r( [
0 I7 F9 P$ @; X! Q) k- return $result->getDeletedCount();
( F: j9 ^. B1 ?. z! e - }3 k1 S: W( t/ h7 b6 V$ p7 I
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 原
7 E; Z5 F: _$ U$ n7 v" r* l
- 新. L+ Q1 |' q' i9 i$ H4 O
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
, \7 O# r9 y/ ?8 y - $lastId = $resultOne->getInsertedId();
! j" x+ x3 G: o' X - $resultMany = $collention->insertMany($array, $options);//多! \3 c% T5 v* G+ D9 Q+ U' s
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
2 o0 G% j, N# ~) \4 L& ?: D
- $collention->update($condition, [# f; [$ b$ b/ ~/ Y* n7 Y
- '$set' => $values ~& f, Z2 K3 |. q- Y" v7 h
- ,[
0 x% z, X# t% j% L+ r" p - 'multiple' => true//多条,单条false' I" p& @) Y+ t
- ]);
复制代码- 新: T, y2 C) ~) i; y0 i- B
- $collection->updateOne(
5 m4 r* h7 s8 i0 |) N0 \ - ['state' => 'ny'],
# E0 i5 B4 I+ M2 s0 m' w$ f - ['$set' => ['country' => 'us']]
5 n8 N9 K$ f. Q t2 A7 B - );6 h+ R5 u: | l
- $updateResult = $collection->updateMany(
. u/ T1 H& e' [6 y - ['state' => 'ny'],
: I" ~! `' L, w5 [ - ['$set' => ['country' => 'us']]
9 d6 `2 E: v/ @ - );% Q9 D @. t5 g5 V. a
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [; a Y/ s7 x1 o1 q. Q" v
- 'name' => true//指定字段
, O1 G2 u3 D x6 a7 d, V - ]);
2 R$ n" S/ L( u% z6 ^( X - $cursor->skip(5);
8 n# C, u5 v% y4 I. K$ [' R2 e - $cursor->limit(5);
1 q3 z! @ J0 g# {) ]9 f. g3 ? - $cursor->sort([
" c! u) E/ g) ` - 'time' => -1
2 j( B' |1 r# X2 o9 g* \6 ^ - ]);
复制代码- 新& H% T4 k p! w/ ~) H5 P4 C4 @% ^
- $cursor = $collection->find($condition, [' z7 M4 ~6 x+ p/ h
- 'skip' => 5,
. n$ E) F3 p/ h - 'limit' => 5,
1 N' J6 S/ U+ Y5 e( d0 v - 'sort' => [
5 I% H5 q/ ~* G- J8 s - 'time' => -18 L( {3 m Q4 x. @" Y
- ],//排序' R9 w5 G+ X8 ]" ^
- 'projection' => [
9 C2 ~* P2 r* L# J - 'name' => 1//指定字段3 [% M& @; B) \7 C
- ]- s0 O( s4 O- w! c& p8 R/ u% T1 T
- ]);
复制代码 5.删除- $collention->remove($condition, [5 m; h9 ]" c: \- d# o3 R: C
- 'justOne' => false//删单条
9 f! s! f' k% c/ W" p - ]);5 S5 y: f' t: g9 m, a
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
6 _4 x; t' e* t# ?5 r! N - $collention->deleteMany($condition, $options);+ ?$ b6 o# z/ `* _
- % x# {3 k; J" U
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
' Q" K8 U5 }- B0 b* l, g - '_id' => $tableName//我在自增表中用其它的表名作主键* E: [, T9 u% Y- \% J0 Q. M1 Z- a
- ], [) c5 s2 `0 k9 h3 `3 n- a
- '$inc' => ['id' => 1]//自增) O1 {' X1 p! j; `9 F5 x( r5 v
- ], [
$ K) V2 B" ?2 y* u2 h0 L9 f - '_id' => 00 B9 i4 ?9 {% g* _
- ], [6 l% D+ a5 `1 U: R# \- X! T" {
- 'new' => 1//返回修改后的结果,默认是修改前的" z! Y. Q0 Z. }) M7 `
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([4 M( }$ m# N: ]1 i! t5 ~9 S
- '_id' => $tableName! W5 z: b: K/ L7 W
- ], [& e9 `/ `1 ?9 {# Z* V9 A
- '$inc' => ['id' => 1]
+ J/ c) y. j; b6 z: h7 x- y8 M8 g - ], [
% S9 @0 Z8 {+ L' d0 L$ a - 'projection' => ['id' => 1],4 F" o& H2 T5 O% W
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER$ }8 S' k3 O/ n V
- ]);
复制代码 + i; }- N \0 m4 x
0 R+ z8 T: R2 y7 r% ?. }
|