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
y/ v' y- F" ~2 z; t
! F2 T% X9 E" Z0 {$ p/ I- use MongoDB\Driver\Manager;& i- G5 m [6 W8 j; ]9 C6 U
- use MongoDB\Driver\BulkWrite;- o% Q, A5 [* w& Q
- use MongoDB\Driver\WriteConcern;" h& W$ L& J/ p! {+ d9 F3 v
- use MongoDB\Driver\Query;
$ v- i/ C- \8 E - use MongoDB\Driver\Command;
3 `" P1 F7 h7 G( [ - 3 J) P3 Z8 d* h5 D
- class MongoDb {1 e2 C X: c9 f9 @
- : ?, H- j7 O, T& [* J T( q' {
- protected $mongodb;
& U. z/ c- G7 \, |; {1 q8 F - protected $database;; r$ e% u: d! r w* x
- protected $collection;+ K' B& ^7 E* v% x( J7 w8 o
- protected $bulk;: ~2 @3 G5 x' v8 L
- protected $writeConcern;% O! a9 C* a2 p+ |& l5 n
- protected $defaultConfig. C+ j( F# g6 |" g
- = [
& c! L; \% d& j6 P; e( q7 `* u - 'hostname' => 'localhost',2 i, v. ^# V5 h% J: y/ V% V8 d( j
- 'port' => '27017',
' G: _, Q+ t# J7 r! d7 U - 'username' => '',
7 o7 L$ O) P/ x7 C! |, T - 'password' => '',
/ K2 V* Z, x8 o% Y - 'database' => 'test'2 {8 f' e: ]' z) }+ Z4 E
- ];: y J2 p% | i* y
- 5 g! ~/ Y: ~6 H: Z! \2 W7 B) l
- public function __construct($config) {
3 c' v: @5 x! C - $config = array_merge($this->defaultConfig, $config);8 a! x* R* z5 k8 M
- $mongoServer = "mongodb://";2 U7 y9 y5 X% ?( q' j
- if ($config['username']) {
: R4 M' O' H1 e* o$ Z$ A' X, B - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';
7 b4 Q; ~& s0 C, e6 J2 i. d& y. B - }
, Q. Z( R; i7 D4 \, P Z - $mongoServer .= $config['hostname'];' e+ {' [, R6 `% ]7 o+ W
- if ($config['port']) {0 k0 s% m! K5 y" h; O( ^
- $mongoServer .= ':' . $config['port'];
+ g7 V# T9 z, P$ y6 G: V - }! j* h4 q0 \1 n: m2 B2 V2 _
- $mongoServer .= '/' . $config['database'];
' K2 f5 A7 N a8 h5 A
- k) a, e6 l* i/ _8 A- $this->mongodb = new Manager($mongoServer);
3 a+ N) M3 p+ q$ ~- s6 k - $this->database = $config['database'];/ n' k. n9 H7 n" b
- $this->collection = $config['collection'];& D$ [1 ^( E' L; Q+ O/ E& T
- $this->bulk = new BulkWrite();
& O; E3 A: F0 D - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);! S' _/ Q% r- t3 u, a# t! d
- }
/ _! z' R0 {5 w8 r! b - 8 p$ s" e+ J! E" n5 R
- public function query($where = [], $option = []) { I; B) W: w% k1 ?
- $query = new Query($where, $option);) y7 @ c$ u! l1 `
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);- C1 I7 N; W/ c: F0 P
- 2 O+ F5 l& p8 l. D8 \7 E* G- X
- return json_encode($result);4 ~: Z+ x8 _) R, L% K5 E
- }
/ W$ g3 a; h' `# t - 7 H9 X/ a! W( J T
- public function count($where = []) {
! \, g& d" K% G. \ - $command = new Command(['count' => $this->collection, 'query' => $where]);
8 o8 U. y$ }) y" g/ W! y) L - $result = $this->mongodb->executeCommand($this->database, $command);. W) o! T* n$ V7 g" ~
- $res = $result->toArray();
+ }& a7 ~6 [( K: j8 o" x) e5 |- S - $count = 0;. g" n8 C) a% I- u" g
- if ($res) {
& h; n+ H! d3 t6 Y - $count = $res[0]->n;
5 r- ?2 y% ?) S0 ^8 I - }
- K* L3 n2 j* O
. _$ Q b# B( g. }. b0 K/ n- return $count;
* Q$ f* ] W9 b' H/ q - }
2 E7 r- [9 n6 G3 p% u. \
$ W2 R+ p J( Z( I- public function update($where = [], $update = [], $upsert = false) {& |: E: l3 X/ u- h Q! R8 b; y
- $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
% W0 e/ p* S; K: }6 S; [ - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
# c, t; ^& }+ L. } - ' ^# e. T8 }" U9 _
- return $result->getModifiedCount();" }; F" G; {' `# K8 E7 |
- }
" w) j3 w' H. @( m2 M8 k# _% k - 6 {4 \7 t% W- g1 ?
- public function insert($data = []) {2 P5 y- D+ ~1 _0 Y* f0 Z: U
- $this->bulk->insert($data);+ C2 F9 } j) I" N! u, X) v- G
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
6 M8 _: H$ U9 I! M$ l6 S - 3 m3 I @; G2 \# t; e1 [- v2 p
- return $result->getInsertedCount();
8 d) x/ ^. `7 D, {. C - }! f6 {# |; ^) @- @9 _5 g6 D0 b
2 ~$ ^% H9 v" H7 P- public function delete($where = [], $limit = 1) {0 z; G$ D# a& Y; h8 u/ y0 d% |
- $this->bulk->delete($where, ['limit' => $limit]);( }+ c r9 ]. `3 d
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);; n1 w9 e5 m' Y" X, T
0 _( j- x+ u1 `" Q- return $result->getDeletedCount();
0 _$ O1 R5 U2 U - }
* m0 V/ c7 K! s2 v - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原" z5 q( J7 @% g6 J- I5 Z
- 新
& j# v- k; _+ Z7 t! Q1 P- E( |+ k H
2.新增- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
7 W0 o# T! A2 j, F- Z - $lastId = $resultOne->getInsertedId();' c' ]4 e. _/ [* K; ]8 i/ y
- $resultMany = $collention->insertMany($array, $options);//多# k6 H' K* o! p1 v
- $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原: N* R6 e9 _7 ~# }* y! V
- $collention->update($condition, [) B( {. C+ t5 S% H
- '$set' => $values
7 B0 H& u" O( h4 b+ X - ,[
7 H6 r( _$ J/ e* d - 'multiple' => true//多条,单条false
4 N( X2 I1 }/ I0 W - ]);
复制代码- 新5 G4 i7 B' m# A- T! D! l8 U7 q! R1 J
- $collection->updateOne(
k- K _" ~# `/ z - ['state' => 'ny'],9 O" A( O: D+ s r7 ^
- ['$set' => ['country' => 'us']]
! C: O+ c3 G' G( ~ j8 T5 I- i - );2 I$ i* v5 ?0 b
- $updateResult = $collection->updateMany(
5 a5 e- I0 \8 O8 k+ Z1 B3 J( T; X5 Y4 b - ['state' => 'ny'],5 S, u7 D3 y* m, P1 [+ l S% C" X) F8 p
- ['$set' => ['country' => 'us']]
. P! o1 }. H p% Q - );
( ?8 G. e$ O7 C1 V$ O - $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原
( ^- V: |0 E4 d; o/ ~! l1 O
- $cursor = $collection->find($condition, [5 d; K1 s4 p- q; J
- 'name' => true//指定字段7 Q3 O6 q1 O% k
- ]);
! K/ c5 J/ w+ i0 [6 t+ L+ T - $cursor->skip(5);' {! }; B2 |7 f. t9 _: c" `% N
- $cursor->limit(5);* x1 u& ?% A0 Z' z
- $cursor->sort([
1 A( R6 a! d' d5 H - 'time' => -16 ]0 o: @+ q1 W# ?
- ]);
复制代码- $cursor = $collection->find($condition, [- @ v! B. |0 q r
- 'skip' => 5,
' ^+ u/ ?/ J% B# m - 'limit' => 5,4 D# |1 F @2 I& q
- 'sort' => [
% J, J; ]4 b, x$ D" |+ b - 'time' => -17 p0 i# y# e0 ^7 Q i1 ?
- ],//排序
2 k1 H" ]" u# X2 e8 F/ t - 'projection' => [* d+ {9 M# x' j R J9 a
- 'name' => 1//指定字段! u- c4 n1 y$ ]7 z1 B* c4 {& y
- ]
! @; \/ e- o( n4 y5 n - ]);
复制代码 5.删除- 原
5 p0 u6 h5 h8 _5 l% _& |
- $collention->remove($condition, [
/ N7 r: m7 _/ C4 Q7 j - 'justOne' => false//删单条* f+ w) b: s7 d) P1 s
- ]);, i( P; b3 J9 ^0 V. `
- $collention->remove([]);//删所有
复制代码- $result = $collention->deleteOne($condition, $options);
% F% y8 X1 E! ? T - $collention->deleteMany($condition, $options);
+ s4 i2 q' x8 N- D6 U, k - : [% x1 H8 H4 ~
- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
% n3 I8 ~, q! A: x4 |1 n - '_id' => $tableName//我在自增表中用其它的表名作主键3 l' e5 p c# z( {3 \5 X1 M
- ], [, p1 K$ {. x- o# ^/ g9 u
- '$inc' => ['id' => 1]//自增 }! }" X1 V I V
- ], [( @" S2 Y9 F$ C$ }# g4 l" v
- '_id' => 0+ F3 X1 C7 I& J$ \8 l4 ], ]5 D
- ], [; ?( l- A! @) F! T2 F9 t8 b
- 'new' => 1//返回修改后的结果,默认是修改前的
9 w4 Y+ ?* I& g6 V) s7 C - ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([
0 w x. y4 @8 B, w. u - '_id' => $tableName' j8 j* U1 k3 w; T
- ], [
8 J0 } W% W$ a5 z - '$inc' => ['id' => 1]3 ]7 ?+ e" [& L- M3 R2 U4 T
- ], [+ m: K% E+ N) s7 \
- 'projection' => ['id' => 1],
3 I. t: [5 C6 i - 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER, I |! Z; S& K! Y0 c ^: _ a
- ]);
复制代码
8 T+ o7 a2 w+ L6 A- ]6 j- _& }' n$ n; R) i" w" }. v! G$ r
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |