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
, _: E, q3 J' h7 W! ~5 \
( H% z2 B {% ?2 s- use MongoDB\Driver\Manager;: T1 ~# N6 S3 C2 M' u- ^% ]; n
- use MongoDB\Driver\BulkWrite;( f( q0 x8 [8 e. o. Q
- use MongoDB\Driver\WriteConcern;( j. h8 ^" U# v" e
- use MongoDB\Driver\Query;
& X1 Y! N. p8 O6 b0 b! U - use MongoDB\Driver\Command;. W9 q8 g$ h, I6 g0 j
' N: }7 S( L, A! Y( B2 \5 x- class MongoDb {
0 D5 [* W a. N- S8 e* a6 |
6 W r5 ` z' u- protected $mongodb;
" O' z. L) d; I+ G" j - protected $database;
2 x, ^% k2 A, U4 z c3 |6 u - protected $collection;5 k" L7 T- T# `, L
- protected $bulk;
5 x, D: m1 x T - protected $writeConcern;
" P9 `/ z' \: V8 z D - protected $defaultConfig
- z2 |# \: j2 C# F" B! k - = [
- e& X F% i9 ?5 C - 'hostname' => 'localhost', {, q2 G$ Z) ?2 T3 J5 D# a
- 'port' => '27017',
( T. z4 X0 D' L4 D C - 'username' => '',
, [0 \# h$ |8 b v# } - 'password' => '',
6 @5 ]1 J2 G) H+ P7 T$ i* W5 E - 'database' => 'test', \' D/ ?1 E! }) d5 w0 w
- ];
. G# m6 m+ F8 E3 K0 r - % p% i; { I1 @ U2 D) R
- public function __construct($config) {* L5 j" {3 j/ i
- $config = array_merge($this->defaultConfig, $config);( ]5 u. p" w! }- h, K9 x0 C1 c
- $mongoServer = "mongodb://";2 L; o0 E, a4 H, v) B
- if ($config['username']) {
, T- \' f: Y5 ^/ f7 D4 H {/ Z+ X7 A - $mongoServer .= $config['username'] . ':' . $config['password'] . '@';2 c7 y$ e+ f+ f; Q
- }
' A% P- ]$ y& X# l* Y2 c - $mongoServer .= $config['hostname'];
; l3 [8 ~6 y3 X4 d0 g - if ($config['port']) {& D+ G' F& @, \3 H6 n, B
- $mongoServer .= ':' . $config['port'];
' y) G9 `/ X: H3 ^% q1 d }- j1 e* o - }7 y w! v4 B( Y L" P
- $mongoServer .= '/' . $config['database'];! y/ h' D' P# L
4 _7 A1 a# {7 ~9 v0 m# J, u- $this->mongodb = new Manager($mongoServer);5 _+ c) ?6 ?9 v
- $this->database = $config['database'];
; T, q2 b" ~! k" {. G/ S0 J - $this->collection = $config['collection'];
* w [- o# x3 H' i2 f' [' c3 u' c3 m - $this->bulk = new BulkWrite();
% e- k' B, o* J) d; Q; m. H2 S - $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);8 J9 R. A! j) ~& f
- }
! a& ~# M& _4 H/ n* n - 1 \$ p- e% u% A Z
- public function query($where = [], $option = []) {# [2 x- t# |+ Z0 o, M+ U0 _" p
- $query = new Query($where, $option);# {6 H& T) s$ y! ^
- $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);
6 Q2 i2 R& i" \" z$ X - , }! y7 H" z9 }, N" R% T8 G3 C y
- return json_encode($result);
2 A3 J# y1 n$ W$ x7 T - }
; `4 K' \2 N8 J' I - , b' a4 ?+ S9 i# C3 N0 L) u
- public function count($where = []) {
# ?: B" F; [2 I( [: c, q/ R - $command = new Command(['count' => $this->collection, 'query' => $where]);5 J+ k$ N; i5 e2 t) n
- $result = $this->mongodb->executeCommand($this->database, $command);. L: }3 n* Q! r5 n. ~, V
- $res = $result->toArray();- z; U: L9 n; f: t$ d6 B( G3 y' |& r
- $count = 0;
1 s4 C" A8 U+ R7 d; E* ] - if ($res) {
+ @! K5 K& `1 O4 X/ } - $count = $res[0]->n;
- l5 c& k3 U7 g: ?* o9 r - }
) Q Y3 ]3 c4 o; M! I5 V& U. C
# R& `" F- N9 ~0 C- return $count;
# N) g" U K* q& U0 S4 A - }" Z6 {) t; }& v/ K
- 1 S6 U6 j% O9 l/ f+ L- m5 u
- public function update($where = [], $update = [], $upsert = false) {
j% I* a, W+ R) ?7 [7 Z$ ]! ] - $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);8 ~+ n( V# R. ~/ O% r+ o% Y
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);3 z2 ~: u* ^" }
/ N' S) {/ f$ _- return $result->getModifiedCount();9 {" b% y+ _# S1 n! ]# Y- c' A. b- l5 P
- }3 H. U) |# G" C) w
& N5 _4 ]- L) V9 C/ q0 D0 O- public function insert($data = []) {; R {$ B" _7 b. a7 h9 B0 r
- $this->bulk->insert($data);
% ~* B7 @- I5 v/ \3 P4 h - $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);# \8 u- o \ B O
. L4 Q2 r; D0 ]/ H9 A7 U- return $result->getInsertedCount();
! `* j% J) x# V! N7 O. Q( s - }" ?, h- p) o' k: ]& N# c8 s1 [" X% j
' D+ [* ~3 y# J! u- public function delete($where = [], $limit = 1) {/ o# G4 {/ x* O6 j
- $this->bulk->delete($where, ['limit' => $limit]);: Y- J b Q: q. ]: W* G7 _; ^
- $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
$ o. y k' w6 Z7 p - . t8 y; ~2 |# I& u1 y$ z& {
- return $result->getDeletedCount();
~5 u& G: A5 ? - }
+ @6 u0 v4 z: F - }
复制代码这样的语法和之前差异太大,改动不方便,换 PHP MongoDB 库
MongoDB 库1.连接- 原! A7 @1 m" w% E6 C' m+ ~
2.新增- 原6 `7 E8 t: b5 [' @3 T7 l. N' X
- $collention->insert($array, $options);
复制代码- $resultOne = $collention->insertOne($array, $options);//单
. s, m) @; j, S" @7 k( ^5 s l - $lastId = $resultOne->getInsertedId();
- c, B0 O0 A0 y" v5 P - $resultMany = $collention->insertMany($array, $options);//多
$ d# Z! O) S5 H1 h. D c - $count = $resultMany->getInsertedCount();
复制代码 3.修改- 原( p9 Z! f2 ^8 h1 w5 p2 X8 @6 X* [+ S3 D
- $collention->update($condition, [
4 x7 \3 |3 |" T! `3 O - '$set' => $values
4 F, a+ g5 n0 x# m& J - ,[7 j/ f$ S1 S* _: P* y
- 'multiple' => true//多条,单条false
) T3 F4 f) t: G4 X - ]);
复制代码- 新
* b e6 g! I6 P# T+ H9 l' W
- $collection->updateOne($ g# P6 e9 H5 Y& X1 ^2 ~' m. A: F
- ['state' => 'ny'],
. z; `8 J6 ~4 [; A+ y; Y3 b2 @- w - ['$set' => ['country' => 'us']]/ R8 \9 Q4 S" C/ {( ^
- );
7 `) D; y% w& B7 m' F - $updateResult = $collection->updateMany(
# z* O9 D; N0 L; z - ['state' => 'ny'],
( M8 I9 K3 ?8 j9 z r+ r% c( d - ['$set' => ['country' => 'us']]
9 }, D: `5 S6 l4 L/ j$ T - );% j& V9 }( y- F3 W y
- $count = $updateResult->getModifiedCount();
复制代码 4.查询- 原( M& B) i5 v2 N1 `; [5 W; j
- $cursor = $collection->find($condition, [
7 _+ [$ o, ]8 j# j - 'name' => true//指定字段7 b- D3 Z+ _* P1 w$ L
- ]);
( W% c8 U8 J) Z - $cursor->skip(5);
/ I; V% ]' t4 |( h0 m" o5 n% \. R - $cursor->limit(5);
/ }+ o) Z8 t6 A( h7 k$ I/ M - $cursor->sort([
( y, g; g: y. m/ V6 E - 'time' => -1* S# `# z7 q F' c! l+ X" x
- ]);
复制代码- 新
& W9 e' B+ L; e4 |5 ^, u+ P
- $cursor = $collection->find($condition, [
. [, _; P. t/ i5 t+ a - 'skip' => 5,& y. k; T# J3 H
- 'limit' => 5, k+ G: u1 j" s" D8 I, w3 y; X
- 'sort' => [7 p/ k E& L: f+ R! W2 _
- 'time' => -10 G( J t8 z# j
- ],//排序" T7 b* f- Z, b/ }
- 'projection' => [
% o& f% m. x; G" @ - 'name' => 1//指定字段
+ j1 E# e% Y3 t2 V! Y4 | - ]8 O* { a. q" r+ U
- ]);
复制代码 5.删除- $collention->remove($condition, [
, H8 E' v. b o* t! B - 'justOne' => false//删单条
$ r# P8 q, u) F* z4 ? - ]);
: |7 d2 q5 I4 j8 w5 a% p" o7 ^ - $collention->remove([]);//删所有
复制代码- 新! g9 w" ~/ m3 S+ g; [( c
- $result = $collention->deleteOne($condition, $options);; w, B: p" h R1 V$ L( R2 Y
- $collention->deleteMany($condition, $options);7 O; ?, R4 s, T7 `* L3 w! B' V9 o7 S
( V$ r& ?. o/ L* W1 `' F# l, F- $result->getDeletedCount();
复制代码 补充有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
- $collention->findAndModify([
9 X" A, t0 s" o1 [( ?' \1 J - '_id' => $tableName//我在自增表中用其它的表名作主键
! X5 E L- {6 I A8 x2 y - ], [
8 i, m& _" T$ ~3 U d# x - '$inc' => ['id' => 1]//自增! s$ r8 @$ j5 s' a1 B) k. H4 Z! W
- ], [
6 }- W, |$ N* j! a2 k - '_id' => 0
7 F# m n' O9 h4 m3 Z" E- m - ], [. t5 I$ q# _6 F1 X! `
- 'new' => 1//返回修改后的结果,默认是修改前的" @3 J3 f- ^ \6 B* |# ] d7 n* s- H
- ]);
复制代码现在使用 MongoDB 库的话需要修改为:
- $collention->findOneAndUpdate([) C- }% u0 x7 u1 u/ U' m
- '_id' => $tableName/ F) S5 f/ P- W/ ^- h5 [
- ], [; x7 }* _7 f7 g* Y- @
- '$inc' => ['id' => 1]; O' A! V9 n* n. R: P
- ], [. T/ ]; @6 n6 m
- 'projection' => ['id' => 1],9 I1 @+ _0 B( G7 T4 y; u. D* I
- 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
- n( B' e8 X: H. Q+ n - ]);
复制代码
" h9 i# h3 k8 T6 G2 o/ Z$ L2 n8 }. ~% U' K( I# w: Q
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |