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& ]# k, \/ E* O, L2 }
. n6 u" b* n( A; g2 y/ {; [/ Y! k- use MongoDB\Driver\Manager;
6 j. \+ e) u& T, N - use MongoDB\Driver\BulkWrite;) G1 N3 O# s0 \% l
- use MongoDB\Driver\WriteConcern;
5 [1 v& w- q% |9 W" q; Q; B - use MongoDB\Driver\Query;7 y& N9 y8 t0 t( V0 A% n
- use MongoDB\Driver\Command;
7 P, j% ?' a% L$ n0 ]+ C/ P- } - ' F) J$ R& V1 m2 _8 S6 c
- class MongoDb {
" `: ?% x/ v. {5 ~6 t5 U6 u - * s+ G2 y% \8 t( ^2 m) E
- protected $mongodb;' Z, O" k# a2 X% Z3 N' O0 h
- protected $database;! ^; A1 |- @' e! |7 v: a$ T, H
- protected $collection;& {/ |( \- j3 W# c4 R9 g
- protected $bulk;! x4 m* o4 g5 t) f R% t
- protected $writeConcern;. \8 K' C" R6 S0 X# }- M! z% h3 W$ b0 c
- protected $defaultConfig
L- B: h+ \; C* y5 F - = [
, @* m) P* T# i; l4 m! ` - 'hostname' => 'localhost',
) E5 Q" \6 T/ ^' n- c - 'port' => '27017',
5 K# \2 C7 n% l# a1 q; n - 'username' => '',/ }; K4 O) ~9 P4 l
- 'password' => '',0 r& e( U( U$ I1 [) c
- 'database' => 'test'
$ i* o! g! d' ]5 n - ];
9 q% z$ w; g2 Q6 u6 b: l/ {
& @! Z: _2 U! S- public function __construct($config) { A% z3 m& e! N4 ]2 H3 e5 c
- $config = array_merge($this->defaultConfig, $config);
. e; i, M5 F; m0 j6 q4 J - $mongoServer = "mongodb://";
1 ^/ `' S3 v; q- | - if ($config['username']) { l. G/ I" w. l* z8 P( U
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';- v+ c. C( W2 |( u; U- Y% w
- }0 t& y% L, P4 E
- $mongoServer .= $config['hostname'];
: l: | B6 _" `' O - if ($config['port']) {
; @4 s2 l3 t" D Q \" e - $mongoServer .= ':' . $config['port'];
) _. F |# l @ - }
' T+ A' o& F/ f3 b% k' T - $mongoServer .= '/' . $config['database'];
( |7 ^' G* K1 w - 0 `4 ^+ W( C/ a4 t: F5 J
- $this->mongodb = new Manager($mongoServer);5 A. c/ O3 j. f# O8 X+ q) r$ F( E
- $this->database = $config['database'];
" e/ W7 n/ H1 S* ` - $this->collection = $config['collection'];. J( J. L& k# t" ?9 e% K
- $this->bulk = new BulkWrite();5 u* Q- W8 F& f* }- W
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);/ x+ [* ^0 Y# `+ U" \/ [
- }
' @1 v( S2 q' f! q, \' t
* b [/ O) F6 r* W: ?) E) v! r- public function query($where = [], $option = []) { ?) c- Y% [/ i3 w2 ]
- $query = new Query($where, $option);3 z E5 c# ], N
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);; H* Y+ N5 _& w! c5 v, z, P0 a
1 B) n% \' B9 T* m. r8 W- return json_encode($result);6 I* R0 b$ y# ~0 `
- }
) G9 Y5 s' Q% C& T% o* k
! \" X" j* L" A. C) S- public function count($where = []) {: Z. v2 A% j& ^; S9 X# k# o
- $command = new Command(['count' => $this->collection, 'query' => $where]);& V4 r# a7 l6 M: Y9 F6 G3 R R& d
- $result = $this->mongodb->executeCommand($this->database, $command);6 a, y8 I* n: O' b: q
- $res = $result->toArray();1 Q) L# q) S% n+ [: C r
- $count = 0;8 x5 W/ t) E* t5 E8 Z% D# g
- if ($res) {" V+ h1 O) y+ _+ L ^, C) p
- $count = $res[0]->n;
0 M( P. m8 r+ R9 d0 c m. V3 E - }
4 f& ~, M! K( z' X# L% Y; P* H+ I$ y - 7 v1 Y. \! j4 t" b4 M, o
- return $count;
* A/ ?9 z1 @) i& j+ ` - }
# c! j' o k# Z8 K( j2 o5 O7 X; ` [ - 2 n6 e# Y& O+ T7 k+ @1 q
- public function update($where = [], $update = [], $upsert = false) {
6 i3 @) ?- f8 E' U% I( A( S - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
2 L4 `3 d8 U+ I - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);$ F* _" F% l. A5 n# L `3 y
- 6 j( o Q8 T+ ]4 v4 X d
- return $result->getModifiedCount();
- F( \' q0 M0 n4 p0 Y( c% p - }" ]5 j; }. P: y2 D- e7 ?4 ]1 K
5 g- x/ {) h$ Y" W$ T2 e2 r- public function insert($data = []) {
% i) q! ~. E( w$ X- k - $this->bulk->insert($data);
" u1 t" K4 t* O r& C2 `6 P - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
, J# }5 `2 e% m r - ' l! R& }" j7 F2 Q2 z4 l
- return $result->getInsertedCount();. J: [9 @# U' |7 O
- }
3 i. |. D( T& k$ n - ! Y+ i9 L \9 _+ d" O9 s# a
- public function delete($where = [], $limit = 1) {
- |+ Z5 S E9 ]$ \. N# y - $this->bulk->delete($where, ['limit' => $limit]);
/ Q4 Z2 k: t5 B; | M - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
, }/ k9 x0 I& h& m7 A3 O, J - , H1 P' M: e) @$ ~' a
- return $result->getDeletedCount(); @; @4 H* T, g5 e4 E* F" w
- }
: U& T# _2 ?0 O) g' u. K M - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 新5 N5 `5 Q1 O+ J$ s) S% d- a
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单7 n' ^ o" G8 B# U# W- w4 z
- $lastId = $resultOne->getInsertedId();
' S6 D! {, ~, D - $resultMany = $collention->insertMany($array, $options);//多7 S9 t, f# h/ E
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [
; |+ q4 l' C. h - '$set' => $values& E2 D6 `$ K7 y$ M0 Y7 Z
- ,[, \' i, Z' j1 g1 q" l
- 'multiple' => true//多条,单条false- N h5 `0 ? \5 Y$ t
- ]);
复制代码- $collection->updateOne(
/ X, S5 w3 Q$ D- s% q - ['state' => 'ny'],$ k5 J- o/ O ?2 S, a
- ['$set' => ['country' => 'us']]
$ c' ~* _8 G' H - );
& v0 g& E) Y/ i e" C3 `( f' p$ @ - $updateResult = $collection->updateMany(
' g) [+ B7 I! @% i$ D) K" t - ['state' => 'ny'],
8 F0 D9 ]; J2 G9 q - ['$set' => ['country' => 'us']]
8 P4 P: M5 }8 j7 u4 r3 X - );
8 q+ ] v& R, W - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原9 X8 {! E/ U$ ]9 Y2 d6 Z. m! H
- $cursor = $collection->find($condition, [
# k' u* @: s' W& f. k - 'name' => true//指定字段, t2 c; K: h' v+ D' v& Z
- ]);2 p6 B, v$ w4 E9 N; t) P' v
- $cursor->skip(5);7 }& q7 Z" O+ A) b& Y
- $cursor->limit(5);4 o' R1 ]9 {3 x. D
- $cursor->sort([
7 l3 R' l$ c, y# D! G6 i c$ C" [- k - 'time' => -1- \# Y; `2 e: t" E e3 p
- ]);
复制代码- $cursor = $collection->find($condition, [- \9 _# _3 v! l) G
- 'skip' => 5,
/ j* X. f$ Q n# X: M - 'limit' => 5,
: N, X1 _# A) W - 'sort' => [' p. p/ l0 S# V# N
- 'time' => -1! k7 V" G- j# }1 B k- U$ a3 m$ W
- ],//排序
% [. D6 ~" t [ - 'projection' => [; {$ A3 |5 I" l7 J
- 'name' => 1//指定字段& a8 U# n9 w" C/ G- }7 c" f
- ]
0 ~! V7 M1 C8 f. p, h - ]);
复制代码 5.删除- $collention->remove($condition, [
" C5 m% `" D2 N+ p3 J: Y - 'justOne' => false//删单条/ o* ?2 h! S5 o ^
- ]);
/ x) M; b8 Z8 d - $collention->remove([]);//删所有
复制代码- 新
+ c. D9 n( b7 [# y3 r0 w$ H E
- $result = $collention->deleteOne($condition, $options);
, }3 I1 l5 g' ?! ~ - $collention->deleteMany($condition, $options);
' M& N/ u0 {- g2 ~ - ! R$ p. ?% ~* d: q2 }* n/ C& e- Y
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
5 \. {1 I1 }; z* O, u - '_id' => $tableName//我在自增表中用其它的表名作主键
* l7 R7 O# Z% ]- N* M - ], [
. X. K6 R) z9 p - '$inc' => ['id' => 1]//自增
8 r9 k, r/ T8 f8 ?' X. w - ], [3 |' g- c1 c! J% S J2 x
- '_id' => 0$ w* G. x. }+ S2 C
- ], [' X. R, p2 E! ]4 N
- 'new' => 1//返回修改后的结果,默认是修改前的0 M6 X9 X$ Y. t1 a0 f
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
' z( U% A" g c/ f; i+ O- V7 X3 x - '_id' => $tableName5 q1 W! x* y2 @( [/ C
- ], [" i, ~, T( o- u7 }- v6 r' Q( {
- '$inc' => ['id' => 1]9 [9 X2 ^4 V/ O. H- |' T" G
- ], [
4 `7 I% T) X- d6 ^- L+ b - 'projection' => ['id' => 1],
1 I1 b+ b/ Q' m% p - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER% h! V+ r1 |* d3 `1 u5 m' J
- ]);
复制代码 y. E0 ]* H$ M$ U
- y) W9 R/ {' }2 l
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |