|
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。 但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。 MongoDB 驱动如果使用原驱动的话,大致语法如下: - <?php3 k7 P# C" _9 A
- 8 \ x& N) c; y
- use MongoDB\Driver\Manager;
1 c! I b% A5 Q1 n - use MongoDB\Driver\BulkWrite;
9 i- H5 \ U" ^! U. Q. Z - use MongoDB\Driver\WriteConcern;
3 s3 O- ?4 D8 ?, l: r- y - use MongoDB\Driver\Query;6 ~1 C$ p6 \! o. }
- use MongoDB\Driver\Command;
5 Z' d2 u7 z/ ~9 k2 o - & P& _% U9 q# \7 k3 z) l9 @8 F
- class MongoDb {3 y% g0 j. Q- q$ N" B" `! l& w4 e
- * E; ]/ G8 ?9 D% q, e0 E% `
- protected $mongodb;% J: \4 u) X' W: A
- protected $database;
2 j' u) b( A$ V - protected $collection;" }( o8 w# `- w4 m: ~3 K# J( S
- protected $bulk;2 ` n) ]( o& r6 i
- protected $writeConcern;
9 ^( Y! p/ G5 c) I7 G! x0 u - protected $defaultConfig
7 B, e& z; m" q1 @9 w9 U+ m: C6 a8 | - = [
) ^' F- E4 y! W# p* ]+ o+ g - 'hostname' => 'localhost',
7 a0 A1 n2 ^; o) a8 e# Q* \" \9 M& o - 'port' => '27017',
" _ B: c) g; ~1 }3 h3 G0 r: X - 'username' => '',, Y2 M2 M2 z6 q7 L' ?4 J4 ?3 _
- 'password' => '',
2 I/ z! E* f* Q( ? - 'database' => 'test'3 s% M' v& W& L
- ];
c i' v9 r, B E( X
" z+ l z$ S6 y- public function __construct($config) {
8 V3 W7 O/ s1 C6 @, B& s$ F- W) m - $config = array_merge($this->defaultConfig, $config);, j6 `; ~* s/ T @
- $mongoServer = "mongodb://";( n2 h; U! n) ^% T
- if ($config['username']) {, Q$ g8 Q0 }1 c; E0 p/ V+ j/ N/ C
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';/ Z2 B8 l8 j# ~* p
- }
( |. z1 r4 x; c - $mongoServer .= $config['hostname'];
3 h4 {0 Z; I( u- O - if ($config['port']) {/ P8 E2 N* d# d" |+ V/ `7 B
- $mongoServer .= ':' . $config['port'];' h, P+ u) L' ~1 o
- }. W+ N- K( P/ q6 H; \7 r
- $mongoServer .= '/' . $config['database'];8 Q. a/ j. P' g
- + {8 _+ }% K9 z% i L
- $this->mongodb = new Manager($mongoServer);
) x4 ~ t% U7 ~ ?5 Y - $this->database = $config['database'];
5 p8 T% E: \# T3 y) ~) { - $this->collection = $config['collection'];2 {3 C9 z3 \$ y0 `* J+ v0 { q H
- $this->bulk = new BulkWrite();& q7 D2 U2 ]" r! {/ x( j( \
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
2 ~! A, M5 \0 v& a# I8 N, e0 | - }
5 ?8 F9 r# ^/ Z+ a: X# b5 I
7 Q: r1 V0 u# A9 z1 [4 f- public function query($where = [], $option = []) {
8 r; A. l* ?1 {/ v - $query = new Query($where, $option);- A, ^& d+ y! U! }- G
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);- H; K! w; l/ k, N& x# {
; k5 }2 A4 i, H) {. i% _& x- return json_encode($result);* J- |4 N9 G0 a0 K* F
- }
6 U$ Q6 l$ ~0 {+ Z! x - 2 q K; |$ \% \1 Z$ {% Y9 }1 y& I& \( G
- public function count($where = []) {
7 N$ _) K# v/ g$ r7 {1 u9 P' U - $command = new Command(['count' => $this->collection, 'query' => $where]);
! s: d% j. x3 X( i - $result = $this->mongodb->executeCommand($this->database, $command);% o2 [; r( o1 T8 u6 `
- $res = $result->toArray();8 M0 H t( Y7 D) h8 B6 {) z
- $count = 0;" L# p1 X$ I+ R9 s8 X8 N
- if ($res) {
. o: _3 @" ?3 V$ z6 {3 r( h1 A+ Q - $count = $res[0]->n;* F; ?% M% u8 B0 n
- }
6 n& K2 c; Y6 {& z. d/ R
U$ l7 B: E `; |- return $count;
0 \! ^ ~3 T8 O - }5 y. h0 i; \. B1 t4 X: |% M
- 3 t J* C' {* C5 X
- public function update($where = [], $update = [], $upsert = false) {
( }. I' K6 k8 F9 s8 K - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
6 S3 n7 h& _: F/ S" n( `( b# X - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);* e* T0 }7 ^; S+ h
( |7 g1 I) { J& X* K: { ]# M- return $result->getModifiedCount();
S# Y% J& N( a, F - }/ U5 o: n- e# t% P* ]
- ) V+ A- g k( W
- public function insert($data = []) {
+ S! ^; h' L. q& q - $this->bulk->insert($data);
) Y9 @% w9 }$ G: [! c' s - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);5 E% I( u$ V4 ^1 C( A+ _+ k
# m4 x4 P; Q- c' o* _" t- return $result->getInsertedCount();( e( z+ l/ ]/ h) r$ Z$ g: \. h0 k" r1 l
- }# C1 S. s/ `6 W) ?4 E: H6 p
- 5 P6 x/ L, Z5 M$ h$ V5 ?; U
- public function delete($where = [], $limit = 1) {
! o: k; [0 G: G) @/ X" s, D" Q - $this->bulk->delete($where, ['limit' => $limit]);
: @; u4 J6 |0 J. U8 i+ c1 I - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
+ k& f9 l5 [5 l
9 ]& {" v3 W& |; e( F- return $result->getDeletedCount();
0 O3 p: W O- X) j/ } - }2 ^7 Q \& ~, A( E5 p& r
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库 MongoDB 库1.连接- 新
# F& p) a, h/ c `5 F" f 2.新增- 原
; y* q- d- `* ~4 M& G6 p
- $collention->insert($array, $options);
复制代码- 新; i. W. }, G$ \# X+ K; I4 h
- $resultOne = $collention->insertOne($array, $options);//单
' _1 w, x- b& f ~! i - $lastId = $resultOne->getInsertedId();
/ x. N& S7 o5 j& _ - $resultMany = $collention->insertMany($array, $options);//多. x0 y5 v' i/ d& ] v0 Q' b, \: j
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原. k. n3 ]( F! \0 W3 H* x8 ?0 M
- $collention->update($condition, [( c4 A( |: D+ h8 F; I
- '$set' => $values0 i e# }' u V$ O" N z
- ,[
8 k0 \( T+ l* O3 z; O1 K$ I - 'multiple' => true//多条,单条false
% V8 u0 d9 G( e) Q - ]);
复制代码- $collection->updateOne(2 j, o$ O: }% R6 b; m# z3 U
- ['state' => 'ny'],3 o' V- t, Y5 ~ ?1 q% F# C; k/ R
- ['$set' => ['country' => 'us']]. Q4 D/ V/ J7 F( {& ?0 ?: F- ]
- );+ `- w# D; R& \' C. H/ j8 B5 `
- $updateResult = $collection->updateMany(
0 ?& T4 W# d6 x' T - ['state' => 'ny'], w, w' y7 u ^0 x
- ['$set' => ['country' => 'us']]0 x6 Y* F$ P# D/ m0 ~* m9 x0 |
- );
d4 O1 M) g5 Q" [ - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
$ }: @- V# n& s8 b/ R# \6 T/ T
- $cursor = $collection->find($condition, [
0 T( {3 p0 P1 H& G4 d1 L8 V" |" U. t8 ?" c - 'name' => true//指定字段* W/ R- y# X& [ }
- ]);
, }* S0 X4 M9 e! U! l7 y& I - $cursor->skip(5);
, w1 i/ J/ s$ o# a6 W- c7 V: o - $cursor->limit(5);
& g/ @- P; z' U# n$ @% ]' ]" n - $cursor->sort([
0 A( |7 r R9 k- C1 t' ?: w - 'time' => -1( `- Q8 I# M; B t% d
- ]);
复制代码- 新4 D- P9 K/ F& I$ z0 x: U
- $cursor = $collection->find($condition, [8 G; M1 O" [) f3 n
- 'skip' => 5,1 ~6 Q! x( g5 _% M: Z/ c
- 'limit' => 5,
1 L/ A/ i& o' _- G4 t+ l: ~& b9 F2 ~ - 'sort' => [' W* O0 X3 Q) e0 ]+ K1 C' S
- 'time' => -13 K1 l5 e& i- o4 K" A
- ],//排序
: K2 l7 j; z$ \. \. j( k - 'projection' => [
; i N. M$ j1 T; F+ v0 H6 u - 'name' => 1//指定字段) J8 j) _4 r) t y
- ]
9 M0 l" h4 F. F) E) v; ?9 C - ]);
复制代码 5.删除- 原6 i: X% w2 `- g. d, y$ \. Z& i. h
- $collention->remove($condition, [
% r( Z6 j/ ^) B) H - 'justOne' => false//删单条
- b$ `6 Q/ w6 Z/ K( j5 f - ]);
9 ` t0 Z* w6 q& H - $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
) |% W, u& L3 H; V( f8 n - $collention->deleteMany($condition, $options);
3 L( L! R9 F/ v" B
1 @4 d- R7 N7 y1 f- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改: - $collention->findAndModify([$ B8 ?. ?7 \$ ~, O5 l
- '_id' => $tableName//我在自增表中用其它的表名作主键
6 I' \( C" s1 A$ E8 A' N - ], [
# A% u/ C6 Q |- s/ @* D3 A) k - '$inc' => ['id' => 1]//自增
. Z4 c0 N* |! A# ~* s7 W - ], [" P3 u; ] o6 G
- '_id' => 00 b9 \7 I0 j w( E# L& |0 f n
- ], [: |9 X( ]5 e% |2 u
- 'new' => 1//返回修改后的结果,默认是修改前的; o+ G' S7 q, _) w: q
- ]);
复制代码现在使用 MongoDB 库的话需要修改为: - $collention->findOneAndUpdate([. A ?, e- n8 g' O8 I
- '_id' => $tableName
3 b1 |* H4 I( w: C% \' s - ], [1 z( H8 T. g1 x9 G
- '$inc' => ['id' => 1]
% d9 p+ J# M" \3 b" W - ], [
5 S' [+ W' t; _; _9 [# d- L5 C - 'projection' => ['id' => 1],
8 R6 D. R0 \" s; T8 @6 `' o& g! c - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER# o, E2 w, ?1 c9 ^% I
- ]);
复制代码
+ ?0 J' M+ m0 d2 s3 g/ B# E1 V7 A% I
|