|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php
7 h1 o1 x* `* R- l$ ^" c4 A2 U5 f - 3 j8 `/ _/ v H$ d" j9 }9 g0 t
- use MongoDB\Driver\Manager;
6 C4 [' c6 z j! m$ L+ Q - use MongoDB\Driver\BulkWrite;
# G0 w, a3 H7 ?8 T - use MongoDB\Driver\WriteConcern;8 i- S7 d3 R( r
- use MongoDB\Driver\Query;
; Y4 L* x9 c# Q) ]% ? - use MongoDB\Driver\Command;) v: f- W& t7 x) J
6 Z$ ^: ~+ ?) E: a/ J- class MongoDb {7 a7 P5 D, l0 s) @
: f( t; c- u' e, O( v- protected $mongodb;
) @/ c) Z& y) G8 w - protected $database;
$ i( b+ @0 M, b' k9 u6 G2 P0 m - protected $collection;
$ `) c/ K6 L1 V' |7 ] - protected $bulk;! J6 v3 @, ?- _# F2 }
- protected $writeConcern;; K+ F S ^4 K( F/ P3 U& P
- protected $defaultConfig+ o; w8 [6 s7 R
- = [! j8 J8 Y4 J. ]) ?+ s+ a
- 'hostname' => 'localhost',
, I5 ~! r3 z0 J$ ^; _1 b+ }5 o1 } - 'port' => '27017',* B5 V5 x; G, J- ~
- 'username' => '',% B- o2 }0 A- ^* t4 P; F$ @
- 'password' => '',! @: ?% s& I5 C; \( D8 F0 m" l
- 'database' => 'test'
- T! D0 H g# v9 q; C0 f) f6 r - ];& R0 @# I4 p8 U& o; a6 [
- $ W" \ p5 x, u! ^5 d
- public function __construct($config) {
, l! z* Q4 s9 }/ I: \ - $config = array_merge($this->defaultConfig, $config);
; Q& p6 ?6 t s* c7 X+ v - $mongoServer = "mongodb://";2 j1 }+ }$ u# ?: _. K1 Q
- if ($config['username']) {
2 m P. m# N4 V& i - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
7 K0 B% N0 g# H& t. {, }! e3 @+ z - }: d$ |' }* @, u! O, S
- $mongoServer .= $config['hostname'];( p1 ]4 v% D# ?, ^5 V
- if ($config['port']) {
6 D% `1 B+ c5 I: M6 b; i - $mongoServer .= ':' . $config['port'];7 @7 g: k: O( w- c3 T
- }% Y% U! M2 {4 X7 a+ R, Q7 f5 r, z
- $mongoServer .= '/' . $config['database'];
0 U/ M) a/ s6 X% K - 2 a9 m: i8 d- X2 [2 D
- $this->mongodb = new Manager($mongoServer);* O) b$ y3 S0 e
- $this->database = $config['database'];
, N+ Y# d1 `6 K - $this->collection = $config['collection'];' M3 E1 q( U4 W' ^' @
- $this->bulk = new BulkWrite();
& I8 z+ N& Y& Z3 I% f9 F5 U" E - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);) S, ]) @' l" p) g! _
- }
8 d+ H% j p5 Z( {% E9 R5 }0 H - 6 r b; ?: D+ E |; f
- public function query($where = [], $option = []) {
4 Z8 e' @7 a N7 T* ~ - $query = new Query($where, $option);5 w; }3 u5 t/ A: A
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
z- E/ ~ Q4 ^) @- i4 T. G# I; k' X - ' T" S4 ` H2 A& E# q
- return json_encode($result); E" Z7 {. T4 [8 ^: N5 P3 o
- }
7 K0 e6 r2 P! a8 |; i4 d/ [) F5 } - . _0 m+ {. b, _% G% u( g# c" L
- public function count($where = []) {( P8 |7 J+ k, Q/ G
- $command = new Command(['count' => $this->collection, 'query' => $where]);& w$ G+ A9 n6 N2 O. l4 Y h! W5 M
- $result = $this->mongodb->executeCommand($this->database, $command);
8 I: D" e1 M+ Z, { M+ D$ y6 U$ O - $res = $result->toArray();: l! l( [ F2 e5 Y
- $count = 0;0 p) X x- Z8 k! S
- if ($res) {
( R+ I& n6 t5 ^$ _- ~ - $count = $res[0]->n;7 t* E8 E: h/ i5 e" _3 N% M
- }
/ X- O) t( m9 s# N0 t
* }1 |! Q+ e9 Q5 {( ]7 f' V* [! z- return $count;0 ?% o! e4 f+ X n# X
- }5 `, a2 ?. b" {) e% V3 l
. x5 ]$ M) P4 M* ] n, t- public function update($where = [], $update = [], $upsert = false) {
- j5 ?. _3 A! U: N- c - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
+ [6 G( n% } ~ Z6 l - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
9 P# r6 K- W' @( w! w - , R( M. y; f6 B8 `+ J8 L. i
- return $result->getModifiedCount();: H& \; U. f8 |/ n3 P7 A
- }
2 I- h! ]6 n: j' ~* O7 |% Y) l - ) g+ l9 X# u/ e3 ?, K
- public function insert($data = []) {
# e/ l. S; i/ n - $this->bulk->insert($data);
0 t& W. X4 p* l" C - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);8 Z' M D7 F- D4 L% n
- ; n! H, Q2 ^! z$ H+ n5 n1 d
- return $result->getInsertedCount();- s% f6 I. [+ B0 j' s: W
- }) \; ~! @6 _$ m5 j. o
- 5 M8 m( ]6 J, d
- public function delete($where = [], $limit = 1) {! X/ {$ O/ F! Q
- $this->bulk->delete($where, ['limit' => $limit]);
0 D$ Q4 Z1 S* p/ V% a5 w! l - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);! y4 V3 x, K8 X/ q: O0 p$ M+ ]% f
- + F' d0 h" u! z4 H3 F
- return $result->getDeletedCount();
: F) y2 |& C+ h) t! L# ] - }( G4 S; d% C# r, [! p
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 新; l1 I# E6 L5 a' l( `$ d
2.新增- $collention->insert($array, $options);
复制代码- 新
5 ~# f, D8 Y- W* Y' C8 W
- $resultOne = $collention->insertOne($array, $options);//单
, @' K" H; G6 | - $lastId = $resultOne->getInsertedId();+ E2 o& N+ F0 o8 z
- $resultMany = $collention->insertMany($array, $options);//多! N! `8 a3 t2 B, y
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
2 @; j* z' }) m# h# Z# E
- $collention->update($condition, [
( p" ~' A" F) m$ J - '$set' => $values% A( P( o4 {6 Z5 p' @
- ,[
) O6 m/ a* N Q7 B" e5 l9 I - 'multiple' => true//多条,单条false0 ?6 m" ?# q: V" s
- ]);
复制代码- $collection->updateOne(+ z. q+ L1 k! x; U3 \* d! E
- ['state' => 'ny'],4 f+ n' x% @# b8 b4 m
- ['$set' => ['country' => 'us']]
3 p$ k! @2 I# e% L: u/ v$ } - );
4 t4 p. c" c1 Y6 K t- D- Q" l8 O, v - $updateResult = $collection->updateMany(8 s. O( F5 D ?& n: v$ Q
- ['state' => 'ny'],7 |3 v" {7 g3 X
- ['$set' => ['country' => 'us']] b; O) J( t; W+ |1 k) U+ B& O
- );; F0 }" ]& V8 N0 V; f# Q+ g
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
8 J+ p! k6 Y0 o4 C/ ?7 d) v
- $cursor = $collection->find($condition, [- ?+ x; e2 s- P0 d: u6 ]9 y2 b
- 'name' => true//指定字段( e& F* x0 w: I ~8 l8 E. N/ v, W
- ]);# i' [0 E9 D4 b+ m
- $cursor->skip(5);
+ L6 z7 F3 ]" Y1 j3 w& j& C" g - $cursor->limit(5);
, e6 ]* f8 q; V - $cursor->sort([* M' i1 q+ {) ^, n1 `
- 'time' => -1' ? D, o; a2 Q. S% C
- ]);
复制代码- $cursor = $collection->find($condition, [1 q4 q# _2 a3 L' ^6 C; T4 m
- 'skip' => 5,) d7 I0 F( x$ W" _) |7 m' U
- 'limit' => 5,
" ^2 M# V4 j) D+ s) ^' ] - 'sort' => [) \+ o! _7 A5 R% V' I
- 'time' => -1
( b/ @" Q w4 B' W- v - ],//排序0 Y& i* w8 L7 E$ J2 ^
- 'projection' => [
* Z! _7 t0 l/ a - 'name' => 1//指定字段" p/ O; ?5 ?" u6 ?1 U% V9 {
- ]" Z/ }: z) u8 ^+ K4 u2 q
- ]);
复制代码 5.删除- $collention->remove($condition, [
: p: H" c% j: B% }& H% { - 'justOne' => false//删单条9 e. q; n/ A) ] x- k; s/ }
- ]);/ c4 }/ C0 E) ?& s5 A% I! `
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
' \9 ?) K/ b( w2 Z4 N- M - $collention->deleteMany($condition, $options);
* w& q7 z+ ~$ G2 F! J" N: f* G. @5 b" C
3 Y& H e6 j6 T7 q0 `- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([
5 u! Y& A6 y! H( L5 D! R* ?) G - '_id' => $tableName//我在自增表中用其它的表名作主键3 v1 C' [ w% H) N( \
- ], [
! ]$ o& }8 L4 I: A0 { - '$inc' => ['id' => 1]//自增
7 n% _9 U( T, O. W - ], [
& _8 Y+ T" y3 j7 k m! y - '_id' => 0
0 S; T n' z1 C# l7 y' U" r - ], [/ F7 o( Y% Z+ ]8 x7 f
- 'new' => 1//返回修改后的结果,默认是修改前的( e. q) i2 D+ ~" ~/ W5 h6 [
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([6 R) u* t: L* W& [
- '_id' => $tableName; C& T' P3 I! ]; ~% G9 \- c
- ], [
% A6 W; C; A d+ N" k* W3 h - '$inc' => ['id' => 1]" c! J: k6 S$ g3 ?% C. {: e
- ], [
! a- t1 x9 j& u4 v, C - 'projection' => ['id' => 1],: Y" U x1 u& X' s( u+ r8 c
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
& w/ f5 r. s$ z8 t4 l' V( _ - ]);
复制代码 $ M) m& a4 Z) K. y
8 ~5 x o0 m: x/ k! k! l9 [; G" q |