/** * 自动给给定集合创建索引 * * @param string $collection_id * */ public function autoCreateIndexes($collection_id) { $cursor = $this->find(array('collection_id' => $collection_id)); $dataCollection = new Data($this->config); $dataCollection->setCollection(iCollectionName($collection_id)); while ($cursor->hasNext()) { $index = $cursor->getNext(); $keys = Json::decode($index['keys'], Json::TYPE_ARRAY); $dataCollection->ensureIndex($keys, array('background' => true)); } return true; }
/** * init * * @see \My\Common\Controller\Action::init() */ public function init() { try { $this->_model = $this->model('Idatabase\\Model\\Index'); $this->_collection_id = isset($_REQUEST['__COLLECTION_ID__']) ? trim($_REQUEST['__COLLECTION_ID__']) : ''; if (empty($this->_collection_id)) { throw new \Exception('$this->_collection_id值未设定'); } $this->getSchema(); $this->_targetCollection = $this->collection(iCollectionName($this->_collection_id)); } catch (\Exception $e) { return $this->msg(false, $e->getMessage()); } }
/** * 逐一统计所有需要统计的脚本信息 * 脚本执行方法: php index.php dashboard run * * @throws \Exception */ public function runAction() { $logError = function ($statisticInfo, $rst) { $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => '', 'dashboardError' => is_string($rst) ? $rst : Json::encode($rst)))); }; $statistics = $this->_statistic->findAll(array('resultExpireTime' => array('$lte' => new \MongoDate()))); if (empty($statistics)) { echo 'empty'; return $this->response; } foreach ($statistics as $statisticInfo) { try { if (!empty($statisticInfo['dashboardOut'])) { $oldDashboardOut = $this->collection($statisticInfo['dashboardOut'], DB_MAPREDUCE, DEFAULT_CLUSTER); $oldDashboardOut->physicalDrop(); } //检查是否存在映射关系 $mapCollection = $this->_mapping->findOne(array('collection_id' => $statisticInfo['collection_id'], 'active' => true)); if ($mapCollection != null) { $dataModel = $this->collection($mapCollection['collection'], $mapCollection['database'], $mapCollection['cluster']); } else { $dataModel = $this->collection(iCollectionName($statisticInfo['collection_id'])); } $query = array(); if (!empty($statisticInfo['dashboardQuery'])) { $query['$and'][] = $statisticInfo['dashboardQuery']; } $query['$and'][] = array('__CREATE_TIME__' => array('$gte' => new \MongoDate(time() - $statisticInfo['statisticPeriod']))); $rst = mapReduce($dataModel, $statisticInfo, $query, 'reduce'); if ($rst instanceof \MongoCollection) { $outCollectionName = $rst->getName(); // 输出集合名称 $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => $outCollectionName, 'lastExecuteTime' => new \MongoDate(), 'resultExpireTime' => new \MongoDate(time() + $statisticInfo['interval'])))); } else { $logError($statisticInfo, $rst); } } catch (\Exception $e) { $logError($statisticInfo, $e->getMessage()); } } echo 'OK'; return $this->response; }
/** * 复制插件集合默认数据 * * @param string $plugin_collection_id * @param string $target_collection_id * @return boolean */ public function copy($plugin_collection_id, $target_collection_id) { $source = $this->findOne(array('plugin_collection_id' => $plugin_collection_id)); if ($source == null) { return false; } if (!empty($source['data_collection_id'])) { $data_collection_id = $source['data_collection_id']; $this->_sourceData->setCollection(iCollectionName($data_collection_id)); $this->_sourceData->setReadPreference(\MongoClient::RP_SECONDARY); $this->_targetData->setCollection(iCollectionName($target_collection_id)); $cursor = $this->_sourceData->find(array()); while ($cursor->hasNext()) { $row = $cursor->getNext(); array_unset_recursive($row, array('_id', '__CREATE_TIME__', '__MODIFY_TIME__')); $this->_targetData->update($row, array('$set' => $row), array('upsert' => true)); } return true; } }
/** * 处理数据中的关联数据 */ private function dealRshData($project_id, $collection_id, $field) { try { $rshData = array(); $rsh = $this->_structure->getRshFields($collection_id); if (!empty($rsh) && isset($rsh[$field])) { $rshCollection = $this->_collection->getCollectionIdByAlias($project_id, $rsh[$field]); // 获取被关联集合的结构 $rshKeyValue = $this->_structure->getComboboxKeyValueField($rshCollection); $model = $this->collection()->secondary(iCollectionName($rshCollection)); $cursor = $model->find(array(), array($rshKeyValue['rshCollectionKeyField'] => true, $rshKeyValue['rshCollectionValueField'] => true)); while ($cursor->hasNext()) { $row = $cursor->getNext(); $key = $row[$rshKeyValue['rshCollectionValueField']]; $value = isset($row[$rshKeyValue['rshCollectionKeyField']]) ? $row[$rshKeyValue['rshCollectionKeyField']] : ''; if ($key instanceof \MongoId) { $key = $key->__toString(); } $rshData[$key] = $value; } } return $rshData; } catch (\Exception $e) { fb(exceptionMsg($e), 'LOG'); } }
public function geoAction() { try { $c = $this->collection(iCollectionName('537e1f8b489619c6668b459f')); //$c->setNoAppendQuery(true); var_dump($c->aggregate(array(array('$geoNear' => array('near' => array(121.43785642996, 31.189866744357), 'num' => 100, 'spherical' => true, 'maxDistance' => 0.089992800575954, 'distanceField' => 'location'))))); } catch (\Exception $e) { var_dump($e); } return $this->response; }
/** * 批量保存字段修改 * * @author young * @name 批量保存字段修改 * @version 2013.12.02 young * @return JsonModel */ public function saveAction() { $updateInfos = $this->params()->fromPost('updateInfos', null); try { $updateInfos = Json::decode($updateInfos, Json::TYPE_ARRAY); } catch (\Exception $e) { return $this->msg(false, '无效的json字符串'); } if (!is_array($updateInfos)) { return $this->msg(false, '更新数据无效'); } $rename = array(); foreach ($updateInfos as $row) { $_id = $row['_id']; unset($row['_id']); if ($row['field'] == null) { return $this->msg(false, '请填写字段名称'); } if (!$this->checkFieldName($row['field'])) { return $this->msg(false, '字段名必须为以英文字母开始的“字母、数字、下划线”的组合,“点”标注子属性时,子属性必须以字母开始'); } if ($row['label'] == null) { return $this->msg(false, '请填写字段描述'); } if ($row['type'] == null) { return $this->msg(false, '请选择字段类型'); } if ($row['rshSearchCondition'] !== '') { if (isJson($row['rshSearchCondition'])) { try { $row['rshSearchCondition'] = Json::decode($row['rshSearchCondition'], Json::TYPE_ARRAY); } catch (\Exception $e) { $this->msg(false, '关联集合约束查询条件的json格式错误'); } } else { return $this->msg(false, '关联集合约束查询条件的json格式错误'); } } if ($row['isQuick'] === true) { if ($row['type'] !== 'arrayfield') { return $this->msg(false, '快速录入字段,输入类型必须是“数组”'); } if ($row['quickTargetCollection'] === '') { return $this->msg(false, '请选快速录入的目标集合'); } } if ($row['isFatherField']) { if (empty($row['rshCollection'])) { return $this->msg(false, '复选项,必须设定“关联结合”,且关联结合为自身'); } } $row['filter'] = (int) $row['filter']; $oldStructureInfo = $this->_structure->findOne(array('_id' => myMongoId($_id))); if ($this->checkExist('field', $row['field'], array('collection_id' => $this->_collection_id)) && $oldStructureInfo['field'] != $row['field']) { return $this->msg(false, '字段名称已经存在'); } if ($this->checkExist('label', $row['label'], array('collection_id' => $this->_collection_id)) && $oldStructureInfo['label'] != $row['label']) { return $this->msg(false, '字段描述已经存在'); } if ($row['isBoxSelect']) { if ($row['type'] !== 'arrayfield') { return $this->msg(false, '启用多选项时,请设定输入类型为“数组”'); } if (empty($row['rshCollection'])) { return $this->msg(false, '启用多选项时,必须设定“关联结合”'); } } if ($oldStructureInfo['field'] != $row['field']) { if ($this->_mapping->getMapping($this->_collection_id) !== null) { return $this->msg(false, '当前集合开启了映射,无法修改字段名'); } $rename[$oldStructureInfo['field']] = $row['field']; $row['__OLD_FIELD__'] = $oldStructureInfo['field']; } $rst = $this->_structure->update(array('_id' => myMongoId($_id), 'collection_id' => $this->_collection_id), array('$set' => $row)); $this->_plugin_structure->sync($row); } // 如果修改了字段名称,那么对于数据集合中的对应字段进行重命名操作 if (!empty($rename)) { $dataCollection = $this->collection(iCollectionName($this->_collection_id)); if ($dataCollection instanceof \MongoCollection) { $dataCollection->update(array(), array('$rename' => $rename)); } } return $this->msg(true, '更新字段属性成功'); }
/** * 导出数据 */ public function exportAction() { try { $cache = $this->cache(); $this->_worker->addFunction("dataExport", function (\GearmanJob $job) use($cache) { $job->handle(); $workload = $job->workload(); $params = unserialize($workload); $scope = $params['scope']; $collection_id = $params['collection_id']; $query = $params['query']; $fields = $params['fields']; $exportKey = md5($workload); $exportGearmanKey = md5($scope->_collection_id . serialize($query)); // 获取映射关系,初始化数据集合model $mapCollection = $this->_mapping->findOne(array('project_id' => $scope->_project_id, 'collection_id' => $scope->_collection_id, 'active' => true)); if ($mapCollection != null) { $this->_data->setCollection($mapCollection['collection'], $mapCollection['database'], $mapCollection['cluster']); } else { $this->_data->setCollection(iCollectionName($collection_id)); } $this->_data->setReadPreference(\MongoClient::RP_SECONDARY_PREFERRED); $cursor = $this->_data->find($query, $fields); $excelDatas = array(); // 保持拥有全部的字段名,不存在错乱的想象 $fieldNames = array_keys($fields); while ($cursor->hasNext()) { $row = $cursor->getNext(); $tmp = array(); foreach ($fieldNames as $key) { $tmp[$key] = isset($row[$key]) ? $row[$key] : ''; } $excelDatas[] = $tmp; unset($tmp); } // 在导出数据的情况下,将关联数据显示为关联集合的显示字段数据 $rshData = array(); foreach ($scope->_rshCollection as $_id => $detail) { $_id = $this->getCollectionIdByAlias($scope->_project_id, $_id); $model = $this->collection()->secondary(iCollectionName($_id)); $cursor = $model->find(array(), array($detail['rshCollectionKeyField'] => true, $detail['rshCollectionValueField'] => true)); $datas = array(); while ($cursor->hasNext()) { $row = $cursor->getNext(); $key = $row[$detail['rshCollectionValueField']]; $value = isset($row[$detail['rshCollectionKeyField']]) ? $row[$detail['rshCollectionKeyField']] : ''; if ($key instanceof \MongoId) { $key = $key->__toString(); } if (!empty($key)) { $datas[$key] = $value; } } $rshData[$detail['collectionField']] = $datas; } // 结束 convertToPureArray($excelDatas); array_walk($excelDatas, function (&$value, $key) use($rshData, $fields) { $loop = function ($value, $tmp) { $new = $value; $len = count($tmp); for ($i = 0; $i < $len; $i++) { if (isset($new[$tmp[$i]])) { $new = $new[$tmp[$i]]; } else { return ''; } } return $new; }; foreach ($fields as $k => $v) { if (strpos($k, '.') !== false) { $tmp = explode('.', $k); $value[$k] = $loop($value, $tmp); } } ksort($value); array_walk($value, function (&$cell, $field) use($rshData) { if (isset($rshData[$field])) { $cell = isset($rshData[$field][$cell]) ? $rshData[$field][$cell] : ''; } }); }); $title = array(); ksort($fields); foreach (array_keys($fields) as $field) { $title[] = isset($scope->_title[$field]) ? $scope->_title[$field] : $field; } $excel = array('title' => $title, 'result' => $excelDatas); $temp = tempnam(sys_get_temp_dir(), 'gearman_export_'); arrayToExcel($excel, $exportKey, $temp); $cache->save(file_get_contents($temp), $exportKey, 60); unlink($temp); $cache->remove($exportGearmanKey); $job->sendComplete('complete'); }); while ($this->_worker->work()) { if ($this->_worker->returnCode() != GEARMAN_SUCCESS) { echo "return_code: " . $this->_worker->returnCode() . "\n"; } } return $this->response; } catch (\Exception $e) { var_dump(exceptionMsg($e)); $job->sendException(exceptionMsg($e)); return false; } }
/** * 设定集合名称,请在SOAP HEADER部分进行设定 * * @param string $collectionAlias * @throws \SoapFault * @return bool */ public function setCollection($collectionAlias) { $this->_collection = new MongoCollection($this->_config, IDATABASE_COLLECTIONS); $this->_mapping = new MongoCollection($this->_config, IDATABASE_MAPPING); $collectionInfo = $this->_collection->findOne(array('project_id' => $this->_project_id, 'alias' => $collectionAlias)); if ($collectionInfo === null) { throw new \SoapFault(404, '访问集合不存在'); } $this->_collection_id = myMongoId($collectionInfo['_id']); $mapping = $this->_mapping->findOne(array('project_id' => $this->_project_id, 'collection_id' => $this->_collection_id, 'active' => true)); if ($mapping === null) { $this->_model = new MongoCollection($this->_config, iCollectionName($this->_collection_id)); } else { $this->_model = new MongoCollection($this->_config, $mapping['collection'], $mapping['database'], $mapping['cluster']); } $this->getSchema(); return true; }