<?php
|
|
namespace DBOper;
|
|
include_once "/Common/CommFunc.php";
|
include_once "/Common/Logging.php";
|
include_once 'RedisOper.php';
|
|
class_exists("\MongoLog") && \MongoLog::setLevel(\MongoLog::NONE);
|
class_exists("\MongoLog") && \MongoLog::setModule(\MongoLog::NONE);
|
|
class MongoDBPool
|
{
|
// 注:由于php特殊原因,单次请求结束后会释放所有内存及链接,window系统下暂时无法处理链接池,故暂时只处理单次请求仅创建一个链接
|
private static $dbConn = null;
|
public static $dbConfig = null;
|
|
public static function GetDBConfig()
|
{
|
if (!self::$dbConfig) {
|
$cfgArray = parse_ini_file("/InterfaceConfig.php", true);
|
$session = "db";
|
if (!array_key_exists($session, $cfgArray)) {
|
\Logging\LogError("Config session key not exists! session=" . $session);
|
return;
|
}
|
self::$dbConfig = $cfgArray[$session];
|
\Logging\LogInfo("加载dbconfig.");
|
} else {
|
// \Logging\LogInfo("dbConfig已存在: ");
|
}
|
return self::$dbConfig;
|
}
|
|
public static function Get()
|
{
|
if (self::$dbConn) {
|
// \Logging\LogInfo("get static dbConn ok! ");
|
return self::$dbConn;
|
}
|
|
$dbConfig = self::GetDBConfig();
|
if (!$dbConfig) {
|
return;
|
}
|
|
$dbIP = $dbConfig["DBIP"];
|
$dbPort = $dbConfig["DBPort"];
|
$dbUser = $dbConfig["DBUser"];
|
$dbPws = $dbConfig["DBPsw"];
|
$dbUser = \Commfunc\GetDecodePsw($dbUser);
|
$dbPws = \Commfunc\GetDecodePsw($dbPws);
|
try {
|
$conn = new \MongoClient("mongodb://" . $dbUser . ":" . $dbPws . "@" . $dbIP . ":" . $dbPort);
|
\Logging\LogInfo("Mongo connect ok: " . $conn);
|
} catch (\Exception $e) {
|
\Logging\LogError('Mongo connect error: ' . $e->getMessage() . " db->" . print_r($dbConfig, true));
|
}
|
self::$dbConn = $conn;
|
return self::$dbConn;
|
}
|
|
public static function Close($conn)
|
{
|
//归还,暂不处理
|
}
|
}
|
|
class MongoDBOper
|
{
|
|
/**
|
* 建集合
|
* @param string $collectionName 集合名称
|
* @param array $indexArray 索引 array("key1"=>1, "key2"=>-1, ...) 1-升序,-1-降序
|
* @param array $indexParam 索引参数 array(), 如唯一索引 array(‘unique'=>true)
|
*/
|
public static function CreateCollection($collectionName, $indexArray = array(), $indexParam = array())
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
$retor = $conn->$dbName->$collectionName->findOne(array(), array("_id" => 1));
|
if ($retor) {
|
return;
|
}
|
$ret = $conn->$dbName->createCollection($collectionName);
|
if (!$ret) {
|
\Logging\LogError("CreateCollection error! " . $collectionName);
|
return;
|
}
|
\Logging\LogInfo("CreateCollection :" . $ret);
|
if ($indexArray) {
|
$ok = $conn->$dbName->$collectionName->ensureIndex($indexArray, $indexParam);
|
}
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
|
public static function EnsureIndex($collectionName, $indexArray = array(), $indexParam = array())
|
{
|
// 1. 将等值索引放在最前面
|
// 2. 尽量将排序字段放在范围字段的前面
|
// 3. $nin和$ne跟索引没有关系
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
$ret = $conn->$dbName->$collectionName->ensureIndex($indexArray, $indexParam);
|
if (!isset($ret) || $ret["ok"] != 1) {
|
\Logging\LogError('Mongo EnsureIndex error: collectionName:' . $collectionName
|
. " indexArray:" . print_r($indexArray, true) . " indexParam:" . print_r($indexParam, true)
|
. " ret:" . print_r($ret, true));
|
return false;
|
}
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
|
#查询单条数据, 以array形式返回内容
|
public static function FindOne(
|
$collectionName,
|
$findArray,
|
&$retArray,
|
$fields = null
|
) {
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
#查找数据
|
if (!isset($fields)) {
|
$retArray = $conn->$dbName->$collectionName->findOne($findArray);
|
} else {
|
$retArray = $conn->$dbName->$collectionName->findOne($findArray, $fields);
|
}
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
|
#查询多天数据,以array形式返回内容
|
public static function Find(
|
$collectionName,
|
$findArray,
|
&$retArray,
|
$fields = null,
|
$sortArray = null,
|
$limit = 0,
|
$skip = 0
|
) {
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
$db = $conn->$dbName;
|
#判断集合是否存在
|
$collection = $db->$collectionName;
|
if (!isset($collection)) {
|
\Logging\LogInfo("Find 表名不存在! " . $collectionName);
|
// 当做没有数据
|
} else {
|
#查找数据
|
if ($fields) {
|
$retor = $collection->find($findArray, $fields);
|
} else {
|
$retor = $collection->find($findArray);
|
}
|
if (!$sortArray) {
|
$retor = $retor->skip($skip)->limit($limit);
|
} else {
|
$retor = $retor->skip($skip)->limit($limit)->sort($sortArray);
|
}
|
|
if ($retor) {
|
$retArray = iterator_to_array($retor);
|
} else {
|
$retArray = array();
|
}
|
}
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
|
public static function Count($collectionName, $find)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return 0;
|
}
|
$dbName = GetDBName();
|
$db = $conn->$dbName;
|
$count = $db->$collectionName->count($find);
|
MongoDBPool::Close($conn);
|
return $count;
|
}
|
|
public static function Insert($collectionName, $arrayInsert)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
try {
|
$dbName = GetDBName();
|
$ret = $conn->$dbName->$collectionName->insert($arrayInsert);
|
MongoDBPool::Close($conn);
|
// (
|
// [n] => 0
|
// [connectionId] => 40
|
// [err] =>
|
// [ok] => 1
|
// )
|
if (!isset($ret) || $ret["ok"] != 1) {
|
\Logging\LogError('Mongo insert error: ' . print_r($arrayInsert, true) . " ret:" . print_r($ret, true));
|
return false;
|
}
|
} catch (\Exception $e) {
|
MongoDBPool::Close($conn);
|
\Logging\LogError('Mongo insert error: Exception: ' . $e->getMessage() . print_r($arrayInsert, true));
|
return false;
|
}
|
return true;
|
}
|
|
public static function BatchInsert($collectionName, $arrayInsert)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
try {
|
$dbName = GetDBName();
|
$ret = $conn->$dbName->$collectionName->batchInsert($arrayInsert);
|
MongoDBPool::Close($conn);
|
if (!isset($ret) || $ret["ok"] != 1) {
|
\Logging\LogError('Mongo batchInsert error: ' . print_r($arrayInsert, true) . " ret:" . print_r($ret, true));
|
return false;
|
}
|
// \Logging\LogInfo('Mongo batchInsert ok: ret=' . print_r($ret, true));
|
} catch (\Exception $e) {
|
MongoDBPool::Close($conn);
|
\Logging\LogError('Mongo batchInsert error: Exception: ' . $e->getMessage() . print_r($arrayInsert, true));
|
return false;
|
}
|
return true;
|
}
|
|
public static function Update($collectionName, $find, $setArray, $upsert = false, $multi = false)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
try {
|
// $options { upsert: <boolean>, multi: <boolean>, ...}
|
// * 更新 multiple VS multi 更新时,需要指定是否更新匹配的所有记录,如果设置为false,表示只更新匹配到的一行。
|
// * 这个坑很大,mongo扩展(php5.x用)里指定字段名为 multiple ,而 mongodb扩展(php7用)里使用的字段是 multi
|
$set = array('$set' => $setArray);
|
$options = array("upsert" => $upsert, "multiple" => $multi);
|
$ret = $conn->$dbName->$collectionName->update($find, $set, $options);
|
MongoDBPool::Close($conn);
|
// \Logging\LogInfo('Mongo update: $ret=' . $ret . ', find=' . json_encode($find) . " set=" . json_encode($set) . " options=" . json_encode($options));
|
if (!$ret) {
|
\Logging\LogError('Mongo update error: find=' . json_encode($find) . " set=" . json_encode($set) . " options=" . json_encode($options));
|
return false;
|
}
|
} catch (\Exception $e) {
|
MongoDBPool::Close($conn);
|
\Logging\LogError('Mongo update error: Exception: ' . $e->getMessage() . ' find=' . print_r($find, true) . " set=" . print_r($setArray, true));
|
return false;
|
}
|
return true;
|
}
|
|
public static function Remove($collectionName, $find)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
$ret = $conn->$dbName->$collectionName->remove($find);
|
\Logging\LogInfo('Mongo Remove:' . $collectionName . ' $ret=' . $ret . ', find=' . print_r($find, true));
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
|
public static function Aggregate($collectionName, $pipeline, &$retArray)
|
{
|
$conn = MongoDBPool::Get();
|
if (!$conn) {
|
return;
|
}
|
$dbName = GetDBName();
|
$ret = $conn->$dbName->$collectionName->aggregate($pipeline);
|
if (isset($ret) && $ret["ok"] == 1) {
|
$retArray = $ret["result"];
|
}
|
// \Logging\LogInfo('Mongo Aggregate: $ret=' . $ret);
|
MongoDBPool::Close($conn);
|
return true;
|
}
|
}
|
|
function GetDBName()
|
{
|
$dbConfig = MongoDBPool::GetDBConfig();
|
return $dbConfig ? $dbConfig["DataBaseName"] : "";
|
}
|
|
/**
|
* 建集合
|
* @param string $collectionName 集合名称
|
* @param array $indexArray 索引 array("key1"=>1, "key2"=>-1, ...) 1-升序,-1-降序
|
* @param array $indexParam 索引参数 array(), 如唯一索引 array(‘unique'=>true)
|
*/
|
function CreateCollection($collectionName, $indexArray = array(), $indexParam = array())
|
{
|
return MongoDBOper::CreateCollection($collectionName, $indexArray, $indexParam);
|
}
|
|
function EnsureIndex($collectionName, $indexArray = array(), $indexParam = array())
|
{
|
return MongoDBOper::EnsureIndex($collectionName, $indexArray, $indexParam);
|
}
|
|
/**
|
* 获取数据,优先从redis中获取,找不到的话再从db中查询
|
*/
|
function FindOne($collectionName, $find, &$retArray, $fields = null, $useRedis = true)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
$redisKey = "";
|
if ($useRedis) {
|
$redisKey = \RedisOper\GetDBRedisKey($dbName, $collectionName, $find);
|
// \Logging\LogInfo("Start to get redis data! redisKey=" . $redisKey);
|
if (\RedisOper\GetHashObj($redisKey, $retArray)) {
|
return true;
|
}
|
}
|
|
// 取不到数据从db取
|
if (!MongoDBOper::FindOne($collectionName, $find, $retArray, $fields)) {
|
return false;
|
}
|
|
if ($useRedis) {
|
if ($retArray) {
|
\RedisOper\SetHashObj($redisKey, $retArray);
|
}
|
}
|
return true;
|
}
|
|
function FindOneSort($collectionName, $find, &$retArray, $fields = null, $sortArray = null)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
if (!MongoDBOper::Find($collectionName, $find, $retFindArray, $fields, $sortArray, 1)) {
|
return false;
|
}
|
if (isset($retFindArray)) {
|
foreach ($retFindArray as $value) {
|
$retArray = $value;
|
break;
|
}
|
}
|
return true;
|
}
|
|
function Find(
|
$collectionName,
|
$find,
|
&$retArray,
|
$fields = null,
|
$sortArray = null,
|
$limit = 0,
|
$skip = 0
|
) {
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
// find多条数据的暂不从redis取
|
// $redisKey = \RedisOper\GetDBRedisKey($dbName, $collectionName, $find);
|
// \Logging\LogInfo("Start to get redis data! redisKey=" . $redisKey);
|
// if (\RedisOper\GetHashObj($redisKey, $retArray)) {
|
// return true;
|
// }
|
|
// 取不到数据从db取
|
if (!MongoDBOper::Find($collectionName, $find, $retArray, $fields, $sortArray, $limit, $skip)) {
|
return false;
|
}
|
|
// if (!$retArray || count($retArray) <= 0) {
|
// $retArray = $find;
|
// }
|
// \RedisOper\SetHashObj($redisKey, $retArray);
|
return true;
|
}
|
|
|
function Count($collectionName, $find)
|
{
|
return MongoDBOper::Count($collectionName, $find);
|
}
|
|
function Insert($collectionName, $insArray, $redisKeyFind = null)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
if (!MongoDBOper::Insert($collectionName, $insArray)) {
|
return false;
|
}
|
|
if ($redisKeyFind) {
|
$redisKey = \RedisOper\GetDBRedisKey($dbName, $collectionName, $redisKeyFind);
|
\RedisOper\SetHashObj($redisKey, $insArray);
|
}
|
return true;
|
}
|
|
function BatchInsert($collectionName, $batchInsArray)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
if (!MongoDBOper::BatchInsert($collectionName, $batchInsArray)) {
|
return false;
|
}
|
|
return true;
|
}
|
|
/**
|
* 更新数据
|
* @param array $upsert 如果查不到对应数据,那么则以更新条件新增一条数据,默认false
|
* @param array $multi 是否批量更新,默认false
|
*/
|
function Update($collectionName, $find, $setArray, $updRedis = false, $upsert = false, $multi = false)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
if (!MongoDBOper::Update($collectionName, $find, $setArray, $upsert, $multi)) {
|
return false;
|
}
|
|
if ($updRedis) {
|
$redisKey = \RedisOper\GetDBRedisKey($dbName, $collectionName, $find);
|
\RedisOper\SetHashValues($redisKey, $setArray);
|
}
|
return true;
|
}
|
|
function Remove($collectionName, $find, $delReids = true)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
if (!MongoDBOper::Remove($collectionName, $find)) {
|
return false;
|
}
|
|
if ($delReids) {
|
$redisKey = \RedisOper\GetDBRedisKey($dbName, $collectionName, $find);
|
\RedisOper\DelKey($redisKey);
|
}
|
return true;
|
}
|
|
function Aggregate($collectionName, $pipeline, &$retArray)
|
{
|
$dbName = GetDBName();
|
if (!$dbName) {
|
return false;
|
}
|
|
if (!MongoDBOper::Aggregate($collectionName, $pipeline, $retArray)) {
|
return false;
|
}
|
|
return true;
|
}
|