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
+ n7 c F3 `) |' O0 b9 T9 P
$ g3 u% ^' J5 p( b- use MongoDB\Driver\Manager;4 H+ [3 g: u- L( v* E4 `; O3 E6 T
- use MongoDB\Driver\BulkWrite;
" W; A. c4 a' Y* @ - use MongoDB\Driver\WriteConcern;
8 z% ]# E4 k' i/ V$ Y - use MongoDB\Driver\Query;
" U; |) N& `& D8 \, L - use MongoDB\Driver\Command;& u/ F: X$ U- ]* {1 S
- ' Q+ S1 k2 v! e' G
- class MongoDb {# K; C$ L8 p+ { s0 K9 n" @: N9 {5 q
5 ?5 D) `% T! l- protected $mongodb;
! q6 ^* V3 |" z - protected $database;
) K2 d4 R$ ~. O5 u O) W6 Z4 a - protected $collection;/ E( o% p3 a! u4 u
- protected $bulk;
R# z9 v# S5 l/ O; X - protected $writeConcern;
1 I. `$ w: w8 T5 L2 S - protected $defaultConfig4 b7 {2 ^3 l M$ q( x
- = [
& z- K* e1 H z5 e - 'hostname' => 'localhost',+ w7 v6 T& t: E* U7 Q+ y( _ b5 b
- 'port' => '27017',
2 r/ V7 w- k% Q- b6 X0 | H" D7 } - 'username' => '',' S) ]% b7 H+ u2 B8 W8 Z [1 b- \9 ]
- 'password' => ''," M. N9 f9 s( b8 D- \5 A
- 'database' => 'test'
& W$ T: r0 t- H! A2 o" F5 t, E1 v% @ - ];
( W2 }' y3 k2 A
0 H7 Z) H4 K2 ^( [+ E- public function __construct($config) {* C% x& t! R8 B% Y2 _9 }
- $config = array_merge($this->defaultConfig, $config);
& B" B2 F( m1 d5 ^ - $mongoServer = "mongodb://";9 k( M( C2 h1 `$ [9 Y" Z& Z
- if ($config['username']) { u% B* e8 M, G0 S5 r1 c
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
) _3 G2 }; v v* m& e4 Z - }# L0 x& Y `5 r7 o
- $mongoServer .= $config['hostname'];. s) H. e) t. K) D
- if ($config['port']) {
* j' |$ h9 |* T" K5 l2 J% i - $mongoServer .= ':' . $config['port'];$ |! n+ Z* { R1 r: v$ R
- }
( w3 h2 f: ~9 \9 b+ t - $mongoServer .= '/' . $config['database'];1 G: d! Y5 V/ y
- ) @2 _: o0 R& q" C$ u0 C* J0 h
- $this->mongodb = new Manager($mongoServer);
2 p+ ~$ n, B3 r7 J - $this->database = $config['database'];+ {3 t5 A9 M0 v: C. Y0 g
- $this->collection = $config['collection'];6 D# }4 J2 v' ^$ j) H
- $this->bulk = new BulkWrite();5 ?: R4 a( G. Q6 L1 |
- $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
% z V- p3 S. D1 U# p: {" R - }
. K& L5 k8 Q& i1 p8 c" p3 } - ! Q; k( W5 m6 a+ O; B" `
- public function query($where = [], $option = []) {
# M6 O& J4 ^( S' g' g - $query = new Query($where, $option);
J' V* n- [6 U% S - $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
( n% J' G* n, r# H+ L* L# s( ?8 o - & z) N4 w# I5 A' s4 r
- return json_encode($result);' L$ w$ {# Q6 `% Y2 _4 B J. ~! X+ V( L
- }
4 q$ J. q1 B& m6 x( g, L
8 f6 [0 Q! @! ?1 v! ]! s+ h( `- public function count($where = []) {% u9 ^- ?) W" @. r* H9 m
- $command = new Command(['count' => $this->collection, 'query' => $where]);7 B) O. J% l( X- L3 r4 [
- $result = $this->mongodb->executeCommand($this->database, $command);1 n1 N; B7 i+ c$ p
- $res = $result->toArray();
, B% ~$ z L7 ?0 k: h2 J - $count = 0;
8 l% J* D5 G+ \ - if ($res) {' F9 I& m& v K1 I7 `
- $count = $res[0]->n;
. b/ h o8 z U; K: N1 l - }
% P! n# p1 B! S7 u. V( \4 x - + g# p" B9 z# _4 `# s1 `
- return $count;
- n$ x0 q+ @; y# _7 I3 S4 b( v - }) E* q @9 Q8 l$ F8 b5 c
- " p& {5 f9 j, Y( m9 D" [' A
- public function update($where = [], $update = [], $upsert = false) {
6 Z" W) `$ @/ Q9 d - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);" |1 @- X m6 w* M. T1 E% L a
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
* t) t- [8 R0 p. d; s) D
5 w* m' h5 E( w1 s5 ^! U8 d- return $result->getModifiedCount();
2 \2 u5 t# L9 `1 W; E* H1 l# x7 T - }
! w3 |) n! \' M3 n4 I( K# H - " y* M, w( E! a. M b7 R
- public function insert($data = []) {
$ ^3 E2 e2 l( J; s# m - $this->bulk->insert($data);
* @/ [( i {* }; {" X2 C7 h# W$ N - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
8 u/ H7 S- R2 t! A- A, w) U
6 Q7 V) y* s- h8 `5 L' o- return $result->getInsertedCount();7 @8 R& m8 \9 m" F* w8 ]5 Y
- } l7 ]' L$ Q+ z# h* {' Y2 D
& Y. N3 V+ s# X2 r2 d- public function delete($where = [], $limit = 1) {
8 P- ?( ]3 W) n: L - $this->bulk->delete($where, ['limit' => $limit]); G a/ w& z$ q) ]% U6 v
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
4 k) k7 U4 i3 B6 a
/ s$ w1 y0 S; O- h$ B- return $result->getDeletedCount();0 g, M e% P" [3 k6 Z! A
- }
, Y! B @3 \( ]- K7 M1 H3 V. } - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 新
) T J4 P! y3 {4 X$ n5 Z! K5 H. z
2.新增- $collention->insert($array, $options);
复制代码- 新% O" T- p& j: A9 q' u) [
- $resultOne = $collention->insertOne($array, $options);//单2 M1 A1 \0 d$ j& q. ~$ G ?7 d
- $lastId = $resultOne->getInsertedId();
0 q: e( y' X; i* ^( j: { - $resultMany = $collention->insertMany($array, $options);//多
! B# s. r" d/ M. b& u9 | m - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原2 N& l [- _* E+ \8 V ]2 t! T
- $collention->update($condition, [
: T' r- E }- o9 u; a - '$set' => $values$ d$ |3 ~" W5 G
- ,[
8 N5 _$ Y5 O/ n4 |* ^! f/ U - 'multiple' => true//多条,单条false$ N" e: D$ R. x) s/ P0 ~. t
- ]);
复制代码- $collection->updateOne(9 l8 G0 U8 c3 T' \" h# H
- ['state' => 'ny'],
/ m6 @- ?5 `9 ]) t2 C. e - ['$set' => ['country' => 'us']]
7 r# e* N) k( K - );2 R/ j6 L4 O& c' a+ T1 L5 M
- $updateResult = $collection->updateMany(
! O4 `1 F( h, _0 r - ['state' => 'ny'],
- r ]5 k8 _+ {* _ - ['$set' => ['country' => 'us']]" R' f8 _# A: U- |' B7 F
- );
3 D/ c: U" e. E' g - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [# i4 y' s/ q: r' | T) c
- 'name' => true//指定字段1 }6 _! \" n$ l; _( e4 q" e
- ]);0 V' Z! Y+ z4 B4 d/ d2 z7 X
- $cursor->skip(5);
! P4 f! O; a7 a1 F$ I4 j& [5 [& b - $cursor->limit(5);
+ b) \% m% Q0 w6 O+ p - $cursor->sort([
% O7 y* e6 k o; a" U/ G8 P - 'time' => -1
% S. o, _' }6 n0 N ^ - ]);
复制代码- 新
% U3 H( W, j5 x0 G f* q
- $cursor = $collection->find($condition, [
2 r" |$ B4 V4 ?: S1 {: T! b - 'skip' => 5,
* m, e/ q- q0 n* `# Q7 j% F - 'limit' => 5,
1 o! O# O7 @/ y0 e - 'sort' => [
0 F8 t( {* @" w/ B - 'time' => -1* }3 |+ }8 g& |- M! g
- ],//排序
! F9 }9 i& u& N5 a9 z. R/ W/ U - 'projection' => [3 T8 z! l7 _0 G, D1 y9 Z# ]% r9 d
- 'name' => 1//指定字段# s3 j: Z& r/ P( I" i
- ]- _9 U+ z2 H5 e! N+ F' ^
- ]);
复制代码 5.删除- 原/ V4 e( @% w# P" |7 [3 J
- $collention->remove($condition, [
* J M5 W# I# I4 s- A. X - 'justOne' => false//删单条4 u- _8 W3 ^4 @7 Q
- ]);8 [3 P* \9 T5 m3 r0 x/ |' i6 L
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);/ f; [5 L/ X3 Q9 N; H5 p. V
- $collention->deleteMany($condition, $options);- u6 P: N% r4 V' A/ V0 w
( q" q2 }4 L0 z7 M) u- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([7 S+ C5 M' [, u
- '_id' => $tableName//我在自增表中用其它的表名作主键
1 y$ {5 `' U- g& B. A - ], [
( z5 m, {, C* w& w% y - '$inc' => ['id' => 1]//自增+ V$ u! M# o: m) C2 G# s
- ], [& N" z0 |$ {6 o l6 h5 F
- '_id' => 06 `0 u; G. B3 L0 k
- ], [8 Z y1 u. G4 r5 j
- 'new' => 1//返回修改后的结果,默认是修改前的! J4 _1 a% P/ H9 h
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([# \4 M7 a. |" x
- '_id' => $tableName; u+ ?$ h& ~0 Z" Z3 R* X7 E
- ], [3 t! ?% G: [; p9 z" \5 _, K9 d
- '$inc' => ['id' => 1]+ x5 Z6 ?+ j. u' H( t1 }) {
- ], [; V, Z* ?9 @6 Z# ~6 Y/ w
- 'projection' => ['id' => 1],
) o/ Z! W( B# T+ ?; O- f% r" {. r - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
8 [8 [) n* G) r+ g; \' |. h - ]);
复制代码
. f9 e* S( ~% M' p O2 d+ o
8 E/ F: |( k r7 b6 M% g
欢迎光临 cncml手绘网 (http://cncml.com/) |
Powered by Discuz! X3.2 |