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: `5 h" I9 D9 c% Q( ^ D* ~
- x" ^2 K2 H" ]0 |* p
- use MongoDB\Driver\Manager;
' y* z6 C; i! \ - use MongoDB\Driver\BulkWrite;
5 u: w1 ^ }* {" W |& ?; @* F M - use MongoDB\Driver\WriteConcern;( l+ `* t. ]- i2 w6 I* R& {
- use MongoDB\Driver\Query;2 M7 m# Y2 {$ ~/ N5 Y
- use MongoDB\Driver\Command;
+ P* ]! @4 g- W$ E0 A: z& g
" J; H( R6 h2 U* y! x/ k- class MongoDb {
* l1 m, f0 @# s. ^. }6 e - # ^$ x1 e, {; k* v1 r- l
- protected $mongodb;
; M& a2 ^8 `, Y8 ~- d2 V* g5 R1 ~4 ?8 E - protected $database;" R. T! W+ o& l) F: e; W
- protected $collection;
, m2 Q1 e, ?$ Z# ~4 E/ K% | - protected $bulk;. q5 A( q& |0 }. c: |
- protected $writeConcern;4 z- ~- t" Z' ?; t, O
- protected $defaultConfig
0 D& [" A1 b V2 G! _+ [( x5 u+ M - = [
" c* o Q( H Z9 E2 L& Z - 'hostname' => 'localhost',4 T7 _' T- Q/ Z0 Y7 d" g) B
- 'port' => '27017',
7 E4 z. C% ?" q3 P/ v" k - 'username' => '',' M4 h Z7 ]7 C: G. G& a
- 'password' => '',
7 p+ _3 L1 W, _ l+ h - 'database' => 'test'
* q7 ?5 v* I6 p& D( U - ];
- ]; L5 f- x3 u2 ]" `2 X* S; x
+ T9 _ P+ J8 s% Q6 ?2 ]+ `5 w- public function __construct($config) {
1 O+ r4 z6 F! ~3 r4 C' L! ?+ |* p - $config = array_merge($this->defaultConfig, $config);
! _- L) s+ |% \3 X& U - $mongoServer = "mongodb://";& i: ?# C, j. Z2 y
- if ($config['username']) {, y/ a# F2 @% y% L8 a9 S: v$ M
- $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
3 @0 q c7 O. k }) J/ [ - }
, L, {# m$ s' q( b/ }" L4 _: ` - $mongoServer .= $config['hostname'];
1 C0 \2 {/ H |0 O, P7 h - if ($config['port']) {' f# `* a8 b5 z5 D7 m; m& X, Z
- $mongoServer .= ':' . $config['port'];
, ]- m* i+ {5 H* Z' F - }" R' A- R. ^# v2 f5 F
- $mongoServer .= '/' . $config['database'];
, i. N) y& i; t9 z. V$ z6 k - ( P) L' |5 T5 O" W: v6 {% j
- $this->mongodb = new Manager($mongoServer);
7 o4 h% G, u& |& p5 C! l! { - $this->database = $config['database'];
% {) T) C; e7 ^7 @3 L$ x; f, q( h - $this->collection = $config['collection'];
2 H! r1 @1 i- V& W8 S; T# `% e - $this->bulk = new BulkWrite();
% s- m% s9 A, b' O% Q8 |, H - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);
2 f9 Y% L s+ ?$ V' m - }$ C m: q9 d* T
/ @$ Q# d/ z9 m! N% b1 V# t: W- a: y- public function query($where = [], $option = []) {
1 f7 X* u9 G$ @6 v# ~$ A# x - $query = new Query($where, $option);2 ~+ ?& b5 U" v9 }3 `- ~2 H1 a
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);$ K# u+ M+ C; S" }, m
) b% E. h8 p7 l1 w- return json_encode($result);1 P6 u1 {$ |4 c+ c. s1 y
- }
V3 g. `7 a( L% d$ C - 0 M5 x1 C2 A5 n% \" M8 _3 ?
- public function count($where = []) {- `- N( U4 q0 z$ s1 `% U7 v
- $command = new Command(['count' => $this->collection, 'query' => $where]); Z5 _4 K' d% a8 P
- $result = $this->mongodb->executeCommand($this->database, $command);3 y) g/ j) K Y& p" N
- $res = $result->toArray();
0 t" f& P3 }$ S1 k - $count = 0;
4 z+ _; Y) I. r# e! | - if ($res) {; S/ h8 F- j2 W) y- q
- $count = $res[0]->n;
" s7 ?% B8 k8 ?6 I! A4 K8 [ - }- \/ o' E7 l4 w
h; _0 K. r2 n" `/ X3 G1 B- return $count;) ^6 u4 }% O! w$ o% L' v
- }
& w. Q6 S7 _# [. @ z# G: l! q/ a
9 R& i- h8 W. r) i- public function update($where = [], $update = [], $upsert = false) {
* j1 a1 p' p8 N* I+ j - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]); V+ } T, @8 _" _
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);- F2 ?; Z8 X9 U
. {6 z/ }1 h6 W4 c# E- ^/ Z- return $result->getModifiedCount();
" M( I1 v% s9 }7 u2 @) `" | - }- x' Z2 N3 ]8 L" h
1 ?5 e* t3 A; w0 L9 ^5 p$ `- public function insert($data = []) {
2 X0 |" q c( E: m. b8 a5 B - $this->bulk->insert($data);
@; l# b, W6 z4 V" s K& P - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);. h; B7 M- }; |* `, ]
5 J9 |% s, V0 t: k. k0 U+ I( p- return $result->getInsertedCount();
0 j* R+ _1 z: s8 y - }
7 e4 D: O" b! ^# \+ F( s - 7 J7 ]. Z, p" p5 }: o3 B
- public function delete($where = [], $limit = 1) {) _% F K+ x* y6 _
- $this->bulk->delete($where, ['limit' => $limit]); N5 q# @# X- M( J) B' }
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
% f# O( F4 O0 \ - 5 y7 @. ]. A. o* Z$ Z8 Y7 G9 r
- return $result->getDeletedCount();
8 b$ {) ` h T' B - }
9 U) G8 Y" U/ e4 t u - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原% g# E' C2 ?, ]0 m3 R; L* }
2.新增- 原
1 s. [7 p5 I# j3 Y" ^; p/ m6 U
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
$ [% ~/ ^ B/ L$ F9 T - $lastId = $resultOne->getInsertedId();
2 h8 _1 }8 u8 P' Z0 @. V - $resultMany = $collention->insertMany($array, $options);//多7 ^6 L4 l9 p6 U' }+ o2 v( U
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原- {; p& ?3 ]# q" I7 X( r2 f
- $collention->update($condition, [
6 ]. g$ p. C4 {1 t' u. n1 e - '$set' => $values
' M+ t4 B; p4 ?& n/ S - ,[' V: q, G! w% o8 ?# ~2 D; E' n! C
- 'multiple' => true//多条,单条false1 {% M/ d/ G2 E/ e# l% J! s% x0 J
- ]);
复制代码- $collection->updateOne(
9 p& p% e* D" H* D/ G. s6 U - ['state' => 'ny'],/ ^% i! O9 j$ h7 z+ e. K) V
- ['$set' => ['country' => 'us']]6 c$ N5 u/ V' x- _5 f! Z
- );
7 I# w! [$ a3 ~: v! v+ i - $updateResult = $collection->updateMany(2 \0 v+ K- J3 L j, A$ u
- ['state' => 'ny'],0 q2 X/ N$ S4 _
- ['$set' => ['country' => 'us']]
1 M% _; J* u6 Z9 Q - );
* J% A% _( C7 O) p8 B. t - $count = $updateResult->getModifiedCount();
复制代码 4.查询- $cursor = $collection->find($condition, [
" t9 {, z" x) k( P# Y+ N4 c - 'name' => true//指定字段$ j0 N9 B3 ?7 \# n8 Q5 n4 A
- ]);
, q% Y( u- P* m( }- r - $cursor->skip(5);
d. \1 w, x# `8 Y C5 s - $cursor->limit(5);
. F$ A$ B0 q2 L2 P - $cursor->sort([
. j& t$ Z8 D1 Z6 a5 c- Z - 'time' => -1
" g' ?2 M* \* ]/ b/ Y+ w! g - ]);
复制代码- $cursor = $collection->find($condition, [
$ i' [0 P( o" f. d0 Q! [9 K - 'skip' => 5,( }' y0 y7 c: B/ }
- 'limit' => 5,
( O5 y% d% M6 K* O3 R C - 'sort' => [$ R% M. R0 b" b) T' {: T- I
- 'time' => -1
, a0 ]% X; R# `( R( r! k" d) U4 G - ],//排序
; m$ ^9 ?. d9 _5 `) n2 N - 'projection' => [' S! G+ @* y. G- @% l
- 'name' => 1//指定字段
. i4 n a# C5 k! `5 k0 i- m Q - ]! s4 `3 w* X4 e- @" F% l' h
- ]);
复制代码 5.删除- $collention->remove($condition, [2 J+ o2 Q, _8 k# H
- 'justOne' => false//删单条
" ?+ x: q6 Q9 g: U8 D - ]);( q8 c2 N" { J3 L. n
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);3 X8 ~1 a8 F+ c3 {, O% K
- $collention->deleteMany($condition, $options);8 e7 }! A% E+ E
- 1 o$ K4 p/ D' L
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([* I$ {: d4 [& q" Q
- '_id' => $tableName//我在自增表中用其它的表名作主键& \7 M% B% a% P" g; ^1 m! ]: C& V$ o
- ], [' |! s5 d0 I: C1 W" m- O
- '$inc' => ['id' => 1]//自增
+ |% X5 W- S( v% o - ], [
; \& D' P& {6 m - '_id' => 0* C/ H' S# V9 Y& z+ `
- ], [$ g3 x% a$ `" m5 u1 V! k9 d0 e* @$ ^
- 'new' => 1//返回修改后的结果,默认是修改前的
$ W8 g, s2 u) F( q - ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([0 ?! U7 X' B/ c6 @: r+ K3 ?
- '_id' => $tableName- d" {' ^$ a! a' x3 s' \
- ], [/ a. Z3 w' @* w5 F
- '$inc' => ['id' => 1]5 i1 e/ b% f2 P) T( n+ x1 t
- ], [
. V, ~2 T; O8 `9 E \1 n) m( u0 ^ - 'projection' => ['id' => 1],
) q8 Q9 Z) d& R6 ` - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
' L0 S( K5 u$ E0 }! z* t* w - ]);
复制代码
, X5 b, H3 z c: z& J8 _
) v$ w' Z* v# o' j
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |