cncml手绘网
标题: 升级PHP7操作MongoDB [打印本页]
作者: admin 时间: 2019-3-19 14:24
标题: 升级PHP7操作MongoDB
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。
但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。
MongoDB 驱动如果使用原驱动的话,大致语法如下:
- <?php
) j7 e& I; I3 L8 k0 D3 K - ! Z% ~) ?( q8 `$ I
- use MongoDB\Driver\Manager;/ K, ]; h* N+ o& q6 \& \
- use MongoDB\Driver\BulkWrite;. F3 X; w2 m5 k' E: N8 v
- use MongoDB\Driver\WriteConcern;
& d6 F R e0 K7 L) J Q+ @' G3 h - use MongoDB\Driver\Query;/ m& C% s$ }! x+ I
- use MongoDB\Driver\Command;. y) d x7 ~' h4 [5 Q
4 h% l- y+ F. ^/ g8 j0 w/ P# v- class MongoDb {% b% v2 ^! Z6 G+ e1 P
" \1 Y' J1 z8 y6 r/ q/ v- protected $mongodb;
( Y2 n. B! {' O. N, M - protected $database;& U5 j* [$ L& ^ o/ R; D; \
- protected $collection;1 u3 R7 ]" ~" C5 Q1 ]
- protected $bulk;
7 l/ K3 A P5 W - protected $writeConcern;
* L. x% K- K) F, d. i" z' U - protected $defaultConfig
" _5 [; K6 D1 k% _) E. F" h - = [
$ N8 T8 r- D# w/ g" Y - 'hostname' => 'localhost',6 ` G4 Z8 \% S/ P0 M. X( _% n
- 'port' => '27017',
, g& I" `# K+ F: W0 Q# J - 'username' => '',
. x( W6 q! o1 k/ W6 N - 'password' => '',7 ?1 f& P/ V' r8 D, j# ?$ z6 ]
- 'database' => 'test'+ r3 f3 g4 A1 L' {& b
- ];
, u0 k" ?( e; a0 D- E - ! w$ K$ x9 F: l1 @
- public function __construct($config) {1 C/ g& D2 q% h+ \4 n' m" m( [
- $config = array_merge($this->defaultConfig, $config); o" u; |6 z& I
- $mongoServer = "mongodb://";
8 @3 X) Q$ N; }4 _& K+ H - if ($config['username']) {
! E3 M- D* M. A1 l1 \0 T% I - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
7 D- y/ I4 w9 d% ~& G/ v - }& Q* U% C) h3 z# h
- $mongoServer .= $config['hostname'];
: M! O# _! @5 k8 ` - if ($config['port']) {9 O1 I( E7 C' a0 T2 q
- $mongoServer .= ':' . $config['port'];4 r6 X0 V! U9 K7 i8 H4 d
- }5 G3 u( z+ W* n# Z8 H. R q9 y
- $mongoServer .= '/' . $config['database'];
9 `1 ?) {) K. O9 ?' k: g - c! r6 x* _. O4 o% R& x
- $this->mongodb = new Manager($mongoServer);3 X4 ]! H+ J9 ` s
- $this->database = $config['database'];
! M N7 Z9 c; q3 V - $this->collection = $config['collection'];
. ]6 S" l6 s# i+ M - $this->bulk = new BulkWrite();
' z3 Y; U( O$ P6 a - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);& \1 s$ F. e( ]2 ?6 Q( w
- }
0 V5 r8 q' C1 T- i8 w! M; a - / Z; a+ n i c! x. g" Z% D. O5 f
- public function query($where = [], $option = []) {' t9 a$ w% ]8 F) o6 L
- $query = new Query($where, $option);
" R. Z' {$ E; B# ?# ^, p - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);; q, m `" ^+ g& w; A
( T1 {; I; ]: A* ?- return json_encode($result);
; L8 q _* r) o. P9 a7 d+ ^8 k - } D7 t& H1 N& V- ]5 b! K
4 C6 b4 l$ S5 | h3 d- public function count($where = []) {! a- L) l/ F3 C3 }$ S3 X
- $command = new Command(['count' => $this->collection, 'query' => $where]);) {" V6 w6 c0 J, j, D. S
- $result = $this->mongodb->executeCommand($this->database, $command);
^: l8 z; w- B2 O) v) G - $res = $result->toArray();! r! a! [9 \8 Q1 K0 c
- $count = 0;
. `! |% O8 c2 ?' H. O% n - if ($res) {
' o8 w- G [ F) q; I' p1 V7 k - $count = $res[0]->n;* L% x6 r/ O9 \0 W
- }
' U) r/ L5 ?' b
1 A- i' O- ?" z0 ]' H2 S' Z" ~1 r( q- return $count;
H5 l; }* N+ B# D, [ - }: x6 T: R+ {6 C; d S
' Z& J. R+ {( V: a. o9 Y- public function update($where = [], $update = [], $upsert = false) {
" }6 K) K7 F) m) Z: P j6 V - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);0 W9 T" S4 c, M8 { Z6 E
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern); I4 c' x" B- X
- ) l9 [9 H, ~1 E+ L
- return $result->getModifiedCount();' P. E: W- J8 B+ k' w
- }& {' `7 C l' v+ h% {
- 9 q9 s' \& n( I
- public function insert($data = []) {- _- v' u6 b# G1 @% p
- $this->bulk->insert($data);
0 Q3 X- H2 S2 r/ o# m: w( B& Q - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);: v9 X- Z* P; |& }+ t
9 t# W. j* ?# l) d. C4 o6 c% @4 l- return $result->getInsertedCount();
- u* Q3 {! [9 B, n$ e; e P9 o, A - }0 H- a& ^" B" g& X
- * Z" s/ _8 L8 I3 D% n) x" s( K
- public function delete($where = [], $limit = 1) {
; ]- `& j; Q4 k+ b+ k - $this->bulk->delete($where, ['limit' => $limit]);; j9 l; F1 _( Z* Y1 O* W- I" I
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);$ \1 f8 F- q4 u7 c6 ? ?. x
- 4 e/ ?* {8 c9 _1 H
- return $result->getDeletedCount();
- ]9 x' h+ N7 Z, L; A# u - }
8 C7 [$ h# A% D! w5 i* H( x - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原
Y2 W4 l. f+ K1 \6 e- \% S" K
- 新) }! W( J4 P7 w! D! q n9 m
2.新增- 原; t' ^2 O/ Z6 x* B# u) _; G' z
- $collention->insert($array, $options);
复制代码- 新, }- ^$ \9 O- K8 T' G" N, g. m
- $resultOne = $collention->insertOne($array, $options);//单6 W9 m+ J) X6 s6 |+ X! J8 _) B- [
- $lastId = $resultOne->getInsertedId();- p" }& z5 _5 I; u
- $resultMany = $collention->insertMany($array, $options);//多
3 k; D2 ]& H$ c/ R$ Z7 Z - $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [
; v; j, U% X. y4 c; R - '$set' => $values$ W: e6 ?0 Y2 P; l4 M$ \9 F; \& x
- ,[
8 h, U4 K# N: ]# h - 'multiple' => true//多条,单条false
3 Y" D- R6 E; ~5 {* b - ]);
复制代码- 新
5 X5 _* |; _0 m5 H5 P& Q
- $collection->updateOne(
0 i) i! o+ s4 Q) Z; _! Y - ['state' => 'ny'],
& }- J2 m$ a( p; S+ s4 O% `& g - ['$set' => ['country' => 'us']]5 z$ n4 ~3 l) t) D& l& \9 Y5 A
- );* Q6 M% s# A: B& w
- $updateResult = $collection->updateMany(9 u/ x X5 Z( k' U! q8 E
- ['state' => 'ny']," h/ @8 V) @" P# [
- ['$set' => ['country' => 'us']]* @7 e4 o/ K4 I
- );# K4 |0 t) N- ~: }" |
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原+ P: j7 q4 Q, H6 @- \7 i( Z: a+ M
- $cursor = $collection->find($condition, [
6 v' t* r- @0 B6 C' X+ u6 [ - 'name' => true//指定字段( G3 W0 L: d4 }! ]& {" g- ]
- ]);
- g/ j. C+ |1 r& s7 L. Z - $cursor->skip(5);
+ a, S% d1 \% l8 q' U2 M% s - $cursor->limit(5);! A F1 L# \ M5 V
- $cursor->sort([: b2 |$ B# Z- a- _4 w; k7 K* e- [3 d
- 'time' => -1
1 C/ |- T2 _5 y# S! Z Y - ]);
复制代码- $cursor = $collection->find($condition, [
1 } a) Z, l) m0 w5 N) I- \ - 'skip' => 5,
% q* Y3 P! `; d6 A - 'limit' => 5," [- @/ z& N7 S7 J& J) l% ?6 ~
- 'sort' => [
2 C5 D% i. s$ n" \ |: E- E- B I - 'time' => -1
4 @; R* E( u1 p% |4 \1 ~: @" h$ P$ @ - ],//排序! T' n) _. I+ |- d- o: u. {
- 'projection' => [& l$ C* `# k' P# |9 F% d+ ^
- 'name' => 1//指定字段0 y6 ~1 h; G+ G9 S7 K! s6 f
- ]( i3 o3 I6 @+ |& c+ S
- ]);
复制代码 5.删除- 原
3 f: M, ^6 D- _- ^! T2 m
- $collention->remove($condition, [
/ i& ]* o! f4 h. r! \( s; Y - 'justOne' => false//删单条
0 O" u4 S1 X. V. B D - ]);
2 \. G9 J# |! _( _) h ~1 A - $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);; |- Q6 P8 X1 ^. ? Q5 J2 i
- $collention->deleteMany($condition, $options);8 A, o% e j4 [- V K
- % S) `1 ^$ {9 Y* b" M
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
% ]$ y/ w3 j% [8 X- ~* V - '_id' => $tableName//我在自增表中用其它的表名作主键! P1 r/ _. Z7 ~8 c7 j" W
- ], [
. [; E f; g) K7 D" x) e! _ - '$inc' => ['id' => 1]//自增. q# U/ I- X' L5 U! n
- ], [
( K' x; ?3 q% ~& Z9 P! C - '_id' => 0
5 t4 f5 f/ u( F! M( E! P0 y( y - ], [ a7 U! P. }/ o! C7 s4 f: }1 L/ l" W
- 'new' => 1//返回修改后的结果,默认是修改前的) n7 k7 ? F: I
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
1 \; h; O; W- l8 ~7 i - '_id' => $tableName% k: ~& }4 R8 x2 k( z
- ], [
3 Q$ I5 B+ j3 |: j" M$ N - '$inc' => ['id' => 1]
- s4 g: f- G; b+ n: c7 w% k/ r$ o% i7 ^ - ], [
) s& ~! M a% J5 D - 'projection' => ['id' => 1],: ^3 ~5 p8 q1 S+ T
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
1 _, X- p+ X8 M6 P - ]);
复制代码
. G2 E. e# p4 _& o, \* G* u% N; {4 \! H# D
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |