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
* ~0 f$ W: K+ V - 9 f6 I! Q, G/ L& f' `
- use MongoDB\Driver\Manager;
( {7 ^1 D9 y0 @: |* V1 ~ - use MongoDB\Driver\BulkWrite;/ o2 b) q, T5 A0 S5 r, k8 w, x
- use MongoDB\Driver\WriteConcern;
0 A& B9 q; Q! N/ e, ^$ k7 b - use MongoDB\Driver\Query;
5 {8 H+ U! j9 f' u3 ? - use MongoDB\Driver\Command;8 m# Z3 @ J" G+ E
' x; Z/ Q5 _2 k7 F- class MongoDb {' y: R5 Z; k3 E$ _/ a
- . H1 a# z/ @. G
- protected $mongodb;
/ a2 S" R% ^) c! ?$ J! O' | - protected $database;
) v! k6 |) q/ D - protected $collection;
. m8 M6 W' i" R7 e' ~ - protected $bulk;& K7 R3 a; E3 D' T; m" h6 @2 a
- protected $writeConcern;. O1 m% A1 ~# t! B: \. T/ K+ B
- protected $defaultConfig4 `; ]0 X6 O, Z( `1 Z `
- = [
/ P/ Q @! p7 ]; n. I9 k, |# K - 'hostname' => 'localhost',
g" C* n" T, m) j- O' k - 'port' => '27017',
8 i& X- N! Z1 J. I) ^1 X - 'username' => '',1 [; H* G2 e6 u5 h
- 'password' => '',
! e" n7 `" v: Y T& ?7 I - 'database' => 'test'
( u; Z6 _8 @) N/ k* i- \' r# ] - ];
: H2 D$ K" u1 e+ D. ]- s - $ G, @( ?' ^" \4 ]+ ^9 o; a! T5 P
- public function __construct($config) {
& Y, W! K F- ]$ l - $config = array_merge($this->defaultConfig, $config);% q: A' \$ ^9 _" n7 n$ t" H& ~
- $mongoServer = "mongodb://";6 Q" c. X/ i' F2 t- h
- if ($config['username']) {
+ t" v) v. ~( ?/ M - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';' `$ R& F7 q( O6 {6 t, Y' K: e; E
- }
1 u3 O1 C+ H8 ^ - $mongoServer .= $config['hostname'];- v4 ?9 l" g( c# V r4 M/ ^3 O
- if ($config['port']) {
& o r! l1 |8 Z; A - $mongoServer .= ':' . $config['port'];
- p2 }# F7 G! f% I3 g. f1 Q' C$ h - }
! ^ u$ C* [/ G* x8 w+ t) L - $mongoServer .= '/' . $config['database'];7 j' ^+ \% }1 {5 F
# E2 V- N* ~, w/ u: g- P- $this->mongodb = new Manager($mongoServer);2 `4 a7 R# z1 |' o4 k
- $this->database = $config['database'];
2 H3 j- F* _) _+ K0 K K, Y - $this->collection = $config['collection'];
9 l. j7 G+ m) y1 h5 j; ~ - $this->bulk = new BulkWrite();
$ r0 o, z, f. s' i. P& _1 D - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);0 j! x3 @/ g' D" \, J3 x3 Q) l
- }6 ?3 q, X, s0 _7 E3 b+ J p
9 ^5 l6 u- ^+ s- l9 f* H, Q: S& h- public function query($where = [], $option = []) {
" O! b8 E: q g+ h4 I. l9 [; c, P - $query = new Query($where, $option);) e, O; ~$ U: U& }
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);+ W; H5 ~: m, w( {2 W7 z2 C
- 4 C: J! _- y9 y/ B; T$ {
- return json_encode($result);
) g* V T2 F, u& j- i9 ? - } e4 I) T- q4 U$ k9 f1 L
- + J' X1 P5 n$ ~# J* Q, ~
- public function count($where = []) {
2 N& t5 w# h6 i5 |* s8 Q - $command = new Command(['count' => $this->collection, 'query' => $where]);# {& U& ?8 R$ S. n8 h$ O
- $result = $this->mongodb->executeCommand($this->database, $command);
# M9 E6 [% L8 w$ k% C- q - $res = $result->toArray();* R C7 Q a# i* A- c Y0 X% d- D G
- $count = 0;
) x1 P0 e1 J( W2 ?& {: k - if ($res) {
, q# W) _. n" R( w z: d7 U - $count = $res[0]->n;- D4 \; I( ?( V0 [& x
- }2 N# @; n6 M9 t( a
- 1 s Y& E0 L* G. d4 A! ~
- return $count;+ A2 {! n) b; L0 x" x$ h
- }. u3 i/ X7 {7 n, J* V
- 4 L9 c6 I: O- Q8 q
- public function update($where = [], $update = [], $upsert = false) {( ]* p N' Q9 u5 M! i
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 C+ J; _' j" i
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
- |, D( {- ]( K' H3 H: ~1 }
8 F9 S$ G. A9 o5 X8 @$ n: M p- return $result->getModifiedCount();
& l _1 J+ @# O4 F - }
. y& D h: b' i - + _0 u9 [0 K n( J: s
- public function insert($data = []) {
0 V9 G8 K5 \' a: x7 a - $this->bulk->insert($data);
9 B: @9 [# c0 }! W - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);2 G3 P! ]" w h+ {" y$ r
+ Y9 z" E# h8 L# q& O: b3 r7 |9 {: e- return $result->getInsertedCount();
n# P. m! {; y - }
3 ~) G- K- e" F5 i$ i$ x6 q - $ R( Y' U# [, ^" @
- public function delete($where = [], $limit = 1) {
) x5 M y; [4 n, ^4 K5 o1 V - $this->bulk->delete($where, ['limit' => $limit]);6 C2 _' H6 c, |" x5 ^! {( T
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
/ H8 h; G6 g2 j/ B - , b# ^( `) j$ ^, G
- return $result->getDeletedCount();3 v+ V4 J! `# {5 D1 S
- }
: X- c1 a( @& |$ a& a - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接2.新增- 原
; z1 \0 F8 a2 b/ h3 e4 c* w
- $collention->insert($array, $options);
复制代码- 新
; p2 l& }; ?# p# ^1 F. E/ K! I8 I) e
- $resultOne = $collention->insertOne($array, $options);//单: N* H+ Y- M' b4 u
- $lastId = $resultOne->getInsertedId();
3 `' V4 b& e- ~; A! r - $resultMany = $collention->insertMany($array, $options);//多, E! E5 v) ~7 X' F# z& ~' g- k
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [
( y u1 L. R- b5 w$ r w; o2 u( x - '$set' => $values9 H m4 L; R& l) F4 g
- ,[
3 ~: N. y+ k4 z$ ~ - 'multiple' => true//多条,单条false+ c/ f# k- c! q+ ~! O( r+ [
- ]);
复制代码- $collection->updateOne(
, T) O. h6 b& \1 R3 @6 L5 W - ['state' => 'ny'],9 S, |- {$ Y7 @% D. m6 T
- ['$set' => ['country' => 'us']]; }& k5 V4 m- b1 I, f$ @
- );
* O/ c/ d0 O8 }4 r - $updateResult = $collection->updateMany(+ z: v! ~ w* y/ w
- ['state' => 'ny'],
( K7 \6 f/ R7 Q5 l8 s, { - ['$set' => ['country' => 'us']]. g3 i, ]1 n; V5 ]+ F1 n
- );
& p6 ]$ A7 j+ z8 @ - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原0 S& S7 j9 g0 i; A1 M, M% C
- $cursor = $collection->find($condition, [- L6 V* O3 T Z1 ^4 h
- 'name' => true//指定字段0 f, f( A. I) w0 g) w3 a
- ]);
9 Z8 u$ k8 O8 t - $cursor->skip(5);" O- E6 j( \: }$ B# n% o2 l
- $cursor->limit(5);7 @! W( R/ m, x8 m
- $cursor->sort([3 Q% e" a# o; _; a: N" l
- 'time' => -14 ?" C' W9 D. N- s4 ^5 M: [
- ]);
复制代码- 新
* ^7 ?# z! X7 l. J( F, J
- $cursor = $collection->find($condition, [
+ f/ l X [* o1 l. r - 'skip' => 5,4 o$ w3 q: V/ p; B8 {$ ]( z6 [
- 'limit' => 5,
) X; Y e" H [7 d% m% n - 'sort' => [+ a- u o5 C( p6 d% n/ V
- 'time' => -1
& ?6 {5 a( l+ E0 a" A - ],//排序
0 g" r( t# i/ q1 @3 l/ K5 G2 _. p& Q - 'projection' => [2 j+ q1 k9 }* Y/ s0 \# f
- 'name' => 1//指定字段
5 h+ p6 G4 W0 f! ]# I - ]$ x+ i0 R7 N, b5 T
- ]);
复制代码 5.删除- $collention->remove($condition, [2 \; p) r: s$ B$ Z. i/ G% @
- 'justOne' => false//删单条
1 i6 L5 a4 L. U/ W! k3 Z/ Z - ]);
; {- x8 }' T0 e8 p) _! @9 p' s# K - $collention->remove([]);//删所有
复制代码- 新
. y$ f7 m+ }( t3 F1 T6 |
- $result = $collention->deleteOne($condition, $options);2 O9 n1 X, P9 t' C
- $collention->deleteMany($condition, $options);
: K- M: `% p& G# m" z+ h
0 P3 A t: I, Z/ h4 k- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([3 @7 _# x, B% m. E7 V( m1 S
- '_id' => $tableName//我在自增表中用其它的表名作主键# b: v0 \: e! L8 q( g
- ], [" G# `) f3 n" x: b0 f6 ~
- '$inc' => ['id' => 1]//自增1 F/ }6 h) u! M* \
- ], [
3 V2 i: j. A7 ~+ a/ p/ G - '_id' => 0$ ~3 g# N5 _3 V( y" ?7 D5 B8 {: f
- ], [
) M" d7 m4 Y8 o( p8 a6 E% O k - 'new' => 1//返回修改后的结果,默认是修改前的! X+ |3 a+ |) i9 p$ [ e- O
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([9 C% @# e) M- Z; z+ t
- '_id' => $tableName- a. ^! _$ @$ a: J
- ], [
( z& A$ @# X' f3 n6 b8 y - '$inc' => ['id' => 1]
6 u( p7 S ?! N. a9 X" _" _ - ], [4 X* Z/ [" l6 F6 k. O# z) l
- 'projection' => ['id' => 1],. H8 c+ Q/ h8 {5 k9 l1 b
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER% s# X# `! p: D5 P( s, p5 S
- ]);
复制代码 6 K+ i+ s8 V5 O* D+ ?
3 J8 G5 v# _2 B
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |