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
; j* D- w! o- w' j7 ` - ( f* n5 y/ [! G& }+ Q3 T/ P0 Z
- use MongoDB\Driver\Manager;
' D+ y- X8 J* S8 Z* u) l A$ R - use MongoDB\Driver\BulkWrite;
. t; K- [* f: P9 `7 ` - use MongoDB\Driver\WriteConcern;
' X' _ y8 y* Q" G$ n% v; A - use MongoDB\Driver\Query;# M- z* e/ A) H4 J1 F: Z* Q
- use MongoDB\Driver\Command;, p9 I4 e0 X& C& `7 z% u
- 3 k. ^2 O3 \8 z4 A
- class MongoDb {0 i. c, p) u' s
8 v- t% S# E+ g8 ?4 I4 y2 ]4 g- protected $mongodb; M- j0 ?3 J$ H
- protected $database;
7 V$ x% m+ P+ |5 D - protected $collection;) J9 P" F9 S9 i
- protected $bulk;' Y3 ^- }9 l/ _, e
- protected $writeConcern;
( t: y' { c$ W& Y7 r4 L7 @" l - protected $defaultConfig2 \6 [- y' }4 J% |3 A
- = [: R- y, B$ W0 }. s
- 'hostname' => 'localhost',% H/ J6 _" V# ~( K- {, j v; v
- 'port' => '27017',
; v" B# g- ?! f - 'username' => '',
8 z k. H+ K5 s9 T - 'password' => ''," g6 y8 A! S0 Z7 Y, C* u3 G3 z
- 'database' => 'test'
. U$ Q2 H- o4 f/ o4 n; Q; P - ];( a8 x: k& A3 p; ]6 E
' O; D% g& _- U$ j: [- public function __construct($config) {1 `7 |- L* Z) A/ b7 Y5 n
- $config = array_merge($this->defaultConfig, $config); Z8 B7 n* @, J1 v
- $mongoServer = "mongodb://";
( D% W7 w& q7 f3 @; k, Y/ i* J - if ($config['username']) {2 o" j( b* f, I$ S
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';9 S9 p! w9 ]) Z$ m3 ]& w
- }
. w( S |, ~3 k( A+ j, X - $mongoServer .= $config['hostname'];
; C, x7 ]. d f" q- \! w9 Q \ - if ($config['port']) {5 v1 ^ `& {3 s( g6 ^$ n3 h
- $mongoServer .= ':' . $config['port'];6 p3 m5 @7 W% z z
- }* [( A5 m% G5 K) o! P1 j
- $mongoServer .= '/' . $config['database'];
4 }& U; t4 R9 K- f
6 J7 H }) C: F$ C- $this->mongodb = new Manager($mongoServer);$ X9 Q- J4 i! o" }' |( x; }) Y
- $this->database = $config['database'];
# I& I1 s6 R4 w1 n1 Y - $this->collection = $config['collection'];
* h$ r% }# \; [4 O7 b; z - $this->bulk = new BulkWrite();
# {7 i: b4 J6 Y, [ k - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);' Q1 L1 o' O+ {: A5 r! D5 _0 o' Q2 D
- }
" D3 v$ r/ S5 ?( Q b - , V& h3 r, Z) L- H* I
- public function query($where = [], $option = []) {9 s' B7 D7 i4 j( m c1 U
- $query = new Query($where, $option);) m: x. c& o* U$ b' x0 R7 Y% _3 I9 |; H
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);$ B" q% g- y# y0 U
2 o& a" x2 M: G! W" k/ Z2 q/ e- return json_encode($result);" ^4 D0 N; p2 z; x B& p
- }
4 ^2 F- M% O6 O! |& j, R - 6 Y3 o/ s4 b+ r
- public function count($where = []) {1 j3 {, H9 b( V' E2 P% I* B, a
- $command = new Command(['count' => $this->collection, 'query' => $where]);" F. D* o' q7 O
- $result = $this->mongodb->executeCommand($this->database, $command);
. T! t/ r0 y0 q& n- p/ r- d - $res = $result->toArray();
5 C8 v& E% a% B" c" n% h7 U - $count = 0;, ~2 M0 Y* \6 t# ^2 W6 E
- if ($res) {( f6 r6 m1 |" B) Z5 g" m' F
- $count = $res[0]->n;6 g9 \' v/ d5 n# k4 U
- }
' F; @. E& G' a - . ]% K5 x7 F6 u- f+ p3 A0 O
- return $count;8 m* X, m$ C, P: j5 a
- }
/ H* C- h3 o# k% {0 h( i! O9 m( I
/ i; k( ^& `9 a% {- L- public function update($where = [], $update = [], $upsert = false) {) g, ^( q% p) _4 W; b6 C
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 c. _/ n/ S' W( `6 y/ N3 ?: h
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
. T2 ?( G$ w% x2 N0 a
" G5 m8 i/ ?& w, q, X* S/ M: {+ v- return $result->getModifiedCount();
' c+ }) K& X5 G2 {0 y+ ^1 P6 |6 y - }
5 \" Q; p! ?1 S% ?- b
$ H8 @/ G. V6 s F; N N" J. Z- public function insert($data = []) {
1 y, e' @# Q- j, y4 S4 j - $this->bulk->insert($data);
0 V; ~' ]! {* R* D7 C z - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
* }' B9 b$ e2 o
2 C: g v" y) y' F1 I. E! L7 \ v0 l- return $result->getInsertedCount();7 T+ v% O r8 }- t9 ?. c# s
- }( @& K% T% s+ f; H0 k
- ( Q; f; k J# O2 ?3 i, c
- public function delete($where = [], $limit = 1) {4 @, a! n/ @' ^/ I/ |
- $this->bulk->delete($where, ['limit' => $limit]);
! f9 t1 @: o' O1 Z' X6 } - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);- q" c0 i8 G( i5 C5 d* D8 c
- # R# g; W- W9 e' z9 l% P5 B
- return $result->getDeletedCount();3 E/ P: {% x p0 C
- }, _+ G2 P+ y. W
- }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接2.新增- $collention->insert($array, $options);
复制代码- 新- y7 i) y9 e: Z! D' Z2 G, K
- $resultOne = $collention->insertOne($array, $options);//单
( E# \3 D, v! z3 X2 ~ - $lastId = $resultOne->getInsertedId();
, V) \5 d% o S6 s - $resultMany = $collention->insertMany($array, $options);//多6 Q* o! D% Q1 m* J F; U7 A Y# ]
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- $collention->update($condition, [6 i v6 \, u- p: ^: T4 s- V
- '$set' => $values
5 U7 Y4 Z) u( f7 c, k7 E, S - ,[ q) } |, o) ~7 _% Z
- 'multiple' => true//多条,单条false! q. N& Y3 {9 ~- ~) P' S
- ]);
复制代码- 新
3 s4 Z$ W% {! o* ?' M2 c2 T K# i: |* g
- $collection->updateOne(
# f/ N: y4 W" l2 x4 K - ['state' => 'ny'],9 B) F7 S" D! |6 Z( ?: W( T
- ['$set' => ['country' => 'us']]+ W% `' }8 l1 ^6 W
- );- W* L! Z5 n. n0 G6 n
- $updateResult = $collection->updateMany(
; G* i$ ?" i7 v& B* I - ['state' => 'ny'],
_, \) Q1 S+ d - ['$set' => ['country' => 'us']]' j. u; k0 V8 E: A# n8 [ s! X
- );
! t+ Q$ t" v# y |# h6 \ - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
3 j5 p& b9 ?; C6 h4 Q( u
- $cursor = $collection->find($condition, [
! e4 y5 N$ @% l! f - 'name' => true//指定字段: E0 S6 [# U. ?. B5 h
- ]);2 V, ~" A2 \& s6 M5 L1 B0 e
- $cursor->skip(5);
& m" J, Y% K2 M; i) q - $cursor->limit(5);: Z5 b$ z0 N; x+ G- v
- $cursor->sort([% d. h) X, O( Y' |" r
- 'time' => -1 u% R% @% H9 h/ ^( Q, U# q# u
- ]);
复制代码- $cursor = $collection->find($condition, [( U$ z6 a2 ^& w& X3 n5 ~) _, u8 k9 e
- 'skip' => 5,
/ b4 \ S& q4 e4 R/ b - 'limit' => 5,# y! n8 D0 L: L2 u* @
- 'sort' => [
0 o: l! p1 q- k% }5 B6 M, f - 'time' => -1
' }+ g7 L, y) p3 i9 N7 J- D% g - ],//排序
0 g6 I" U& \ X+ m - 'projection' => [
- w u+ \8 k! ]0 F) a - 'name' => 1//指定字段
. k" I3 V0 _6 d5 P - ]
6 M+ u- n* D, G0 i/ ? - ]);
复制代码 5.删除- 原1 k! ^6 y% Y' z4 X% u0 l1 D
- $collention->remove($condition, [
1 d# U+ [' p# E* ~* V" R' N - 'justOne' => false//删单条1 N$ m; f6 I8 i2 H
- ]);
) }. u: N# d6 u3 s! |7 L- U - $collention->remove([]);//删所有
复制代码- 新* M: ~8 Z1 z/ C9 L- _" f
- $result = $collention->deleteOne($condition, $options);
0 n# p, g U$ o: e1 B4 O9 ^ - $collention->deleteMany($condition, $options);$ I- K' ` {. q/ S
3 m, R* v9 j* I2 B- H5 L) k- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([% b6 z6 A0 K! ]2 O- A) W) U+ L" b
- '_id' => $tableName//我在自增表中用其它的表名作主键
: X1 z# I& M- k - ], [3 S- c" j: N( G% J
- '$inc' => ['id' => 1]//自增" f+ ?: l# j2 R+ b
- ], [
8 r$ F) ?( a, y, S+ F! J - '_id' => 05 _% m# ~* m0 L2 z, |
- ], [
+ m2 d4 w' B/ {8 i9 n; w - 'new' => 1//返回修改后的结果,默认是修改前的
5 G! k6 A! g' V1 n& c/ [ - ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
; t G& P8 V3 L" y, ]7 A - '_id' => $tableName
: `9 [' d5 u" V! ~6 t - ], [
! p. b# } A% g! Q( \) t - '$inc' => ['id' => 1]
, P* S- }- a |4 a - ], [' c. K" i& g# Z% ^; `& w
- 'projection' => ['id' => 1], J$ i; I G; E4 b5 f& C
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
; a0 Q5 N( R7 x, Z - ]);
复制代码 . o7 z' j0 Q- B+ E4 |6 a, C
* y& H- |2 L8 y2 m% b6 e. T
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |