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
; s2 G) i, ^( j0 q4 C - 7 a* r- Y$ \, I8 Y2 b
- use MongoDB\Driver\Manager;
" e9 c: }8 n: L9 z - use MongoDB\Driver\BulkWrite;
6 w/ c; U0 s% z0 q0 K3 M: p% S6 f - use MongoDB\Driver\WriteConcern;& S$ d9 Y) E6 I/ d1 q4 F+ k8 _
- use MongoDB\Driver\Query;# S$ D7 s0 K% g( x) U' d
- use MongoDB\Driver\Command;1 y" O! n: v. I$ r; t. ?
1 N' I" s/ `" w) k6 ?( z7 B& Q0 {- class MongoDb {& Y$ b% D: a8 }7 W! a* u" K# G$ l6 |
- ; N1 t8 p9 w' h4 v* s
- protected $mongodb;
9 G1 l7 m M' s: z7 T. t7 q9 j - protected $database;- `$ F( s- v. ]" S5 J
- protected $collection;
* s' `( z1 _1 @- Q: m. Z. V - protected $bulk;
% o' @0 Q! K; {! ^2 W - protected $writeConcern;
1 i; T4 a. C/ a3 \, M, L - protected $defaultConfig1 V: ~( s: a5 h* W+ @
- = [- f5 w4 U+ E h& I# z% R
- 'hostname' => 'localhost',$ c% F0 ?! T) ^3 K" f
- 'port' => '27017',
) h! @2 d' ?# K% W4 S - 'username' => '',
7 {( H, G" c) u3 ?# h2 X, H - 'password' => '',/ w) P+ W+ ], C( B
- 'database' => 'test'
; T4 W1 U/ T, o) E X6 p - ];
" S. d3 S" j; z; e5 k) I9 h1 ]% X - 6 N4 Z& X! r" @+ I
- public function __construct($config) {9 M# x9 ~ Q: v- k6 S
- $config = array_merge($this->defaultConfig, $config);
0 C0 i/ |# b8 s3 I* O- ?8 n4 ? - $mongoServer = "mongodb://";
, R, C- F7 r( O7 X4 {5 X - if ($config['username']) {! f3 r8 f* I: ^9 P j
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
. O) ^* |+ x1 U! d; N - }
4 r5 v: u. x+ Z8 z0 q! O6 s - $mongoServer .= $config['hostname'];
/ e' v8 G6 ^2 E/ C8 _5 T - if ($config['port']) {( ^! |- h( t5 ~/ J) g" y
- $mongoServer .= ':' . $config['port'];) }( ]: V' `( g- d& K8 V
- }1 n# W, a. c& p; x' j
- $mongoServer .= '/' . $config['database'];" H! Z+ y* Z# r% O2 g
. s! K/ }3 d3 z3 R& z3 O- $this->mongodb = new Manager($mongoServer);
4 W" f3 p1 J4 T8 g; Y0 h+ F5 o - $this->database = $config['database'];1 H" b0 O# ]8 m5 a4 A+ a
- $this->collection = $config['collection'];) n. W: h; J: `! f
- $this->bulk = new BulkWrite();
1 m k; Y, @" U4 P - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);5 { y7 }2 _ f% L) u
- } n% g4 ]- k6 b
: f, @5 s: m7 _7 s" h- d2 K- public function query($where = [], $option = []) {3 q" U0 P6 w; q4 O
- $query = new Query($where, $option);* b6 b! q7 @- v: H' h
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);* ~2 a& l" M. Y# ^1 R8 ~
/ m- C# F2 E9 q7 L% y# }4 C- return json_encode($result);6 t- ^5 \4 t& h$ w. ? k9 o5 o
- }
( |; u6 q% z% f4 y/ d - + A$ `6 n0 |# S
- public function count($where = []) {
7 E# n; w& a8 v0 f - $command = new Command(['count' => $this->collection, 'query' => $where]);% I5 Q( r7 k& _; ?) d0 s2 ^/ q
- $result = $this->mongodb->executeCommand($this->database, $command);
" F! j( q2 r) A' i - $res = $result->toArray();
. f* Z9 j' k! d7 M - $count = 0;$ T# v! C: b# S( b' a& z0 J
- if ($res) {
- J0 G8 V7 T( J( l) ^, E9 u: I1 G - $count = $res[0]->n;0 \5 x( ~( ?# u# S; e! K
- }0 x& e' t" B ?
- K! ^* [( _2 `3 R2 y7 n2 T
- return $count;' C3 m2 \( n/ g/ ~' N
- }
7 A0 q1 L$ C. \% H
# O! ]- u. }1 O- public function update($where = [], $update = [], $upsert = false) {7 U; v0 X9 @( g
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
1 Z& P6 Q) ~* c7 S3 A - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
4 h5 a* W% [8 A
0 U0 v# G! U) _( J- return $result->getModifiedCount();7 d I4 y; e: c
- }
+ _0 J w1 \6 d/ j - ) Q$ c$ r! [" g3 L
- public function insert($data = []) {
4 w1 Z( N j- y9 K - $this->bulk->insert($data);' K" Z! R) l' b3 S2 n* }
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);8 G. ?! W1 ?8 N- z2 U" u
+ L- j; ]$ L7 A; B- return $result->getInsertedCount();. \+ e( t2 e2 l" u& w5 C
- }' t# F8 j/ E2 T0 n2 x D# I
- % V V; _; c( H [# q( o5 [
- public function delete($where = [], $limit = 1) {* J( E5 _9 \. y5 T5 G7 |
- $this->bulk->delete($where, ['limit' => $limit]);% J6 P7 ~: c% I' H5 }: N0 J8 d
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);+ b) m8 e# H0 ?3 p
- ( d7 c9 K2 T3 O3 L
- return $result->getDeletedCount();! H2 T- u6 P {2 G4 A" }% q* M5 V- Q
- }& d% [! l I8 Y5 [- M! x5 {0 ^
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原
/ ^1 \5 ]/ d; q7 P) {7 i/ ~5 g# a
- 新
X, x' p6 J4 ~8 t/ p. u! Z0 u
2.新增- 原! S7 C, q( S6 ~ i \. L2 C/ H
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单4 c( i! Y/ p% C# m5 P
- $lastId = $resultOne->getInsertedId();
$ j8 V) r- b5 U+ Z7 f+ E - $resultMany = $collention->insertMany($array, $options);//多
- Z# P1 Y/ H" \: \& E& { - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
3 h# Z T! U/ G/ [+ O# d) e
- $collention->update($condition, [
( g2 ~7 {4 |2 ^/ r9 t( q9 q - '$set' => $values
6 h2 ]& z( T$ u; s, A4 O - ,[- ?! @: d' `" U6 P
- 'multiple' => true//多条,单条false* r7 M, u2 h, E0 K0 z# T
- ]);
复制代码- 新1 Z: y4 k2 a9 V% Y. o+ m! Q) B6 e! {4 P
- $collection->updateOne(( z( O! D* ^" @- G9 ?$ |5 ~
- ['state' => 'ny'],
4 @+ {! d+ L @- I/ b* \ - ['$set' => ['country' => 'us']]
" [- |) w2 |& ?1 E8 \ - );
+ U' x% O! V" e2 B I( A" i - $updateResult = $collection->updateMany(( m6 J" T) O# f- o7 S7 w; m6 u
- ['state' => 'ny'],
" c- f. P0 R& M; R* C& E/ u! {, T$ | - ['$set' => ['country' => 'us']]
* }2 g7 ?3 W+ h - );/ `2 Q8 I- O& G/ L6 @' |
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
2 L3 u X$ p: v9 Q. N- S
- $cursor = $collection->find($condition, [
6 T) T( `2 E4 s. i. D - 'name' => true//指定字段, f' r9 V# k0 ?. Q$ w t
- ]);
. O/ ?. s) o7 x$ q1 a/ M - $cursor->skip(5);
' z4 x; t. j) b3 m$ L; M - $cursor->limit(5);
# [- \. L, N. h: X - $cursor->sort([
4 s# ` X+ n# d4 Y1 o' ?8 Q4 | - 'time' => -1
& Q# y% e2 [: d, F" J1 c0 o - ]);
复制代码- 新
' f3 L, v! B5 q# |' m& |2 j' ]
- $cursor = $collection->find($condition, [/ L" s" f* W" b5 m# H; d0 e5 b
- 'skip' => 5,
. d: I9 Z8 Y1 g% ]) j% q, ~, I2 F - 'limit' => 5,* u( h+ c; J, n% q# d
- 'sort' => [
% d8 S3 @& m/ ?4 P H- C - 'time' => -1
# I( v* i0 @$ j0 u( H) c - ],//排序, ?, y8 K; K" C, z
- 'projection' => [; H( p* p) O. w( }* F- e
- 'name' => 1//指定字段
& g: f. t& N3 G" V, |0 O/ A- H - ]$ H ]4 x+ a# a( N
- ]);
复制代码 5.删除- 原
6 l! z. {" X3 O5 w/ q0 B7 _$ v4 A) x
- $collention->remove($condition, [* J/ T( t. e8 @" C# B" z
- 'justOne' => false//删单条4 E( a4 M$ t# c
- ]);; T! O( f1 h% q6 y: ~* b" v
- $collention->remove([]);//删所有
复制代码- 新7 U2 H! ]8 s, f! O6 h2 E
- $result = $collention->deleteOne($condition, $options);4 K; e1 { C$ `4 Z( x0 U
- $collention->deleteMany($condition, $options);4 f) F) k9 ^. f% Q, _8 g: G+ i8 r
8 v: [3 d; B4 M p7 K; D- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([' E2 \" P u8 h* E
- '_id' => $tableName//我在自增表中用其它的表名作主键
) Q O" K! n& R) F+ } - ], [
! c% ? p2 I0 }# f* I - '$inc' => ['id' => 1]//自增+ W" h9 |+ I" f
- ], [) C/ X$ I# B0 G, K& `0 ~
- '_id' => 0# a' z) I. v2 Z- T
- ], [
+ S$ Y4 [& S) E- s( I+ n - 'new' => 1//返回修改后的结果,默认是修改前的
. k% N* T6 J& u5 q# Z/ ? - ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
* F/ R3 N' U' k/ @: d5 m! T5 | - '_id' => $tableName
7 U) d8 A* X- y6 z7 [- t" x - ], [
6 h j; a# ^; l9 p/ u - '$inc' => ['id' => 1]
$ R6 H- Q+ K2 F1 W2 G/ S - ], [
; I- T+ q% z$ \! B a& \ - 'projection' => ['id' => 1],
* T6 B; z: r- F: r - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER" \2 _; |4 U4 ^/ j8 s% Y
- ]);
复制代码
& c. m* ?; s! t" @$ y9 t1 K) N4 |6 Y5 U- t
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |