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
. U, [& E" m. L. S
* F& M0 y2 }0 B, _- use MongoDB\Driver\Manager;" E' j! ?1 q; c3 e: ?+ ^4 N
- use MongoDB\Driver\BulkWrite;
7 o8 Y' Y( R! x7 D/ G1 T# {; } - use MongoDB\Driver\WriteConcern;; I# [: ~- |7 J, ~0 ^2 _ `
- use MongoDB\Driver\Query;
' w2 ^# I. A( B$ j" o% | - use MongoDB\Driver\Command;; e6 O y1 n/ z; O9 D3 }& j8 ^2 z$ {
- 2 H4 T k1 C. j7 A& j
- class MongoDb {
- a4 | P5 w. W, B4 r( D
8 R, N# t3 V% X N7 \. I" u- protected $mongodb;2 ?% J3 g' S9 _3 H% V: c
- protected $database;7 j% N1 Q J4 J4 j5 R
- protected $collection;
E" W" A# O2 M% `7 a. b - protected $bulk;
5 M: E G1 \ ], f3 j5 W4 [8 f0 W - protected $writeConcern;
/ r8 ?0 i! l0 C4 n* | - protected $defaultConfig
$ r2 T+ G! I$ t - = [
. e- A1 T$ o$ ` - 'hostname' => 'localhost',
[ _% f c( @8 O: b1 Y - 'port' => '27017',$ A0 @ V" C+ ]: F5 L6 ?7 H
- 'username' => '',
t* A0 K- _, {% o - 'password' => '',7 Q' ^3 ]" ~/ [1 y# V
- 'database' => 'test'
2 \* K0 }9 ~6 p2 @8 ]* Z - ];
) y+ @9 a7 T9 ], F) u - ' s/ R$ @* ]5 m" k' z& w% q; R
- public function __construct($config) {
& W& \4 ~4 @3 }6 v: D8 I - $config = array_merge($this->defaultConfig, $config);
% D- ^' W6 L; w( n& Z - $mongoServer = "mongodb://";& i8 G5 g1 J8 o4 b5 m
- if ($config['username']) {
" n0 |1 u$ |: M$ b% b - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';5 i3 U4 v/ Z, ]8 n+ m
- }
& j* b( \9 u0 z z - $mongoServer .= $config['hostname'];7 A# c+ o4 w9 r& W, [) n$ z
- if ($config['port']) {
5 j, q8 ^2 @% E - $mongoServer .= ':' . $config['port'];) Z" A1 b& l/ F; R
- }
$ u2 @9 ^6 L- l; v x0 B% \1 B: k$ O - $mongoServer .= '/' . $config['database'];0 y2 O( o4 T$ G. `: |* Y! R M
+ R5 ` w! \" f2 R& M2 Y- $this->mongodb = new Manager($mongoServer);
3 e5 D0 b$ z$ i$ \: v3 C - $this->database = $config['database'];0 B9 R# T8 T0 Z/ d) G+ O( L; R' H
- $this->collection = $config['collection'];
2 z: J+ M, D0 f9 C( z% G - $this->bulk = new BulkWrite();
1 S+ D0 i' e1 p% \3 I# p5 p - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
6 F: U- j3 N! D - }
6 i8 a1 j, i' K R+ F% r
+ V G; j) G. @- public function query($where = [], $option = []) {
, \/ s9 Y1 U, T. z9 z: _ - $query = new Query($where, $option);# O+ L6 \# v4 P- z7 l2 A B, ?
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);4 ?' o8 Y0 m, H/ _
- 1 j' x0 c5 t; M& s2 t/ ^
- return json_encode($result);/ t7 Z! _# R# |" C$ x$ m8 c
- }
3 \+ T! }- C% |- f% D6 s' | - / ~% C! x* u' v. t
- public function count($where = []) {. N; n% m% Q0 b, u7 D" r. g
- $command = new Command(['count' => $this->collection, 'query' => $where]);
+ j! K0 B9 h2 |4 [. Z& o+ Q - $result = $this->mongodb->executeCommand($this->database, $command);$ o$ K) Q1 b# K
- $res = $result->toArray();4 [, H1 s |% m+ ~3 l; g4 s" i
- $count = 0;
- b( S N2 x4 b8 C5 f- T1 n - if ($res) {
6 P. g) [% i T1 p* W1 n - $count = $res[0]->n;
: D0 q9 E) R! r/ K: ~) b& X - }
& S& c& \6 I6 f% l
+ v5 r+ w6 `( k& K- return $count;% f! k) _0 b9 X) X+ p5 M" A. m
- }
: |# `3 Y$ s' A7 N5 n# c/ Q) C
% i: o- v6 E! P$ u& x% o( K- public function update($where = [], $update = [], $upsert = false) {
$ g1 I- R: Y; a+ A - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);5 V5 [( M1 d, a/ h+ e
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
/ y: D. Y: y3 U5 H# A/ g - ' [3 I4 t0 f% E; T, r1 B
- return $result->getModifiedCount();
# h! f+ V0 ~% L0 {) E$ k - }4 {3 s8 W( P( [9 l5 |6 c
- * L1 e: H; _3 e: b6 M$ _" [% I* H/ k
- public function insert($data = []) {, Q- r3 H; B; D6 D2 }% j9 c" K C3 ^
- $this->bulk->insert($data);
* n5 m) \3 ?! t# ? A - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
P- C9 M3 t" {9 y - 1 `' n# y$ G3 W: s2 J: |/ }
- return $result->getInsertedCount();
2 f! Q! B1 U. X3 R- } - }4 J4 H- O8 p0 w y. N/ ^% E3 {
- ; h$ X) I+ T _
- public function delete($where = [], $limit = 1) {
! W# O9 m0 r3 i; z3 K W- O r - $this->bulk->delete($where, ['limit' => $limit]); q) a+ H5 _- l, @" F0 _. K. H4 t
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
% R. y V' N8 M) a8 v
: ~( w! f) Q9 r( l# W# }1 r0 G% h- return $result->getDeletedCount();
" \+ k$ N; W h/ @; Z$ G - }
7 O4 h$ c9 R6 r9 j. B5 V - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原
* y+ r' w# f0 J1 X4 v5 H
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单+ |7 M( I1 }5 X! H2 R/ \, k
- $lastId = $resultOne->getInsertedId();- z# F M8 A7 ~* l7 Z: G1 x
- $resultMany = $collention->insertMany($array, $options);//多
! g1 r w6 |5 o+ w - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原
0 J9 e% w# v$ r/ M6 m+ w0 t5 F
- $collention->update($condition, [
" o& D+ @1 @" P( ~' i" y& i - '$set' => $values1 x* t1 L, R- C
- ,[0 |& }1 N0 M' h& t
- 'multiple' => true//多条,单条false" }1 p" o6 y! p6 y- \
- ]);
复制代码- $collection->updateOne(3 C# }5 t+ e! B5 G( s
- ['state' => 'ny'],9 k3 y, f( }6 e* |
- ['$set' => ['country' => 'us']]
3 l! ^4 g4 z$ R1 d! W& b1 K - );
+ Z1 h" [0 V& U+ w' p7 e - $updateResult = $collection->updateMany(2 J2 T5 W# t, W
- ['state' => 'ny'],
b0 |' W, W7 \# [& @' V- N5 b - ['$set' => ['country' => 'us']]4 l3 d2 \# Z1 q9 L( `8 Q I( Z& \
- );
6 c) U) B6 F* p: l/ a - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原! J- N3 o4 W! K8 N: Q" h1 p
- $cursor = $collection->find($condition, [
/ \+ @, b q. X- C" ?# W3 O- }4 }$ q - 'name' => true//指定字段$ M% H- w5 M1 p& S4 W
- ]);
6 S3 i- q+ q& c" ? - $cursor->skip(5);
6 [9 T9 X! r% q: `5 v9 Q4 [ - $cursor->limit(5);
. S& R- P. h7 | - $cursor->sort([
: W1 R3 S( v" m2 D% Y* ~! R - 'time' => -1
# x* Q( [# W. [) X - ]);
复制代码- 新* c, N) U M3 i, V0 G0 d' u
- $cursor = $collection->find($condition, [) U* _8 ?8 U0 _8 } f
- 'skip' => 5,* x1 d- M8 k' M. N0 b
- 'limit' => 5," {! e& R4 ~! i! a, Z8 x( l
- 'sort' => [! b7 Y/ \) T) f* p" v7 y
- 'time' => -1. z) u5 p4 Q% C. ?- S0 o
- ],//排序% M" O$ w) C5 q9 I3 s0 Y
- 'projection' => [
) P) r6 o$ ]4 u2 M5 m - 'name' => 1//指定字段5 |. j. H a7 ], z# _- k
- ]" \) f0 C7 v. B7 e* U. g4 n
- ]);
复制代码 5.删除- $collention->remove($condition, [
8 }3 Y* I; P8 i/ l! j8 Y - 'justOne' => false//删单条7 A- Q9 X' J/ I' H3 g) s" Y
- ]);: s, l' v6 \, C
- $collention->remove([]);//删所有
复制代码- 新; b4 D( Q1 y( W; Y# s$ J
- $result = $collention->deleteOne($condition, $options);) a# V8 X, x5 F9 _* v
- $collention->deleteMany($condition, $options);
6 z q& g% J* f
3 |- w. ]1 U4 T+ l3 Q6 \. V6 k* e- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
# F4 c: v: t6 L0 b" m - '_id' => $tableName//我在自增表中用其它的表名作主键. W; ^& j. N& d m- \0 \( y9 }
- ], [* b. L0 ~5 s3 U$ i g
- '$inc' => ['id' => 1]//自增. N! s3 O6 n9 {( y# m7 y
- ], [$ X) M* h- {$ E! Q- i. ]5 J3 t) @3 k
- '_id' => 0
5 i2 V+ `8 F# q) u - ], [& {6 K/ ?# q$ ^* ~! s! p
- 'new' => 1//返回修改后的结果,默认是修改前的* Q8 }' S3 w. A7 D" A$ c
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
% g( h3 X0 Q/ A+ K1 Z8 ^ - '_id' => $tableName
: J& g! x5 b9 S& V - ], [
- U- B6 @/ }3 j# n2 y7 o0 ~ - '$inc' => ['id' => 1]" @5 e6 Q8 T) h. v3 M( H; i
- ], [
. Z3 l( J/ M0 x - 'projection' => ['id' => 1],8 W- ?/ a& ~' }
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER+ t7 _" |4 }. V# `- |4 j
- ]);
复制代码 + t$ r; _. b _' }' w& q6 y; O2 I
% \& s c. o4 C
欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |