Beispiel #1
0
 /**
  * 自动给给定集合创建索引
  *
  * @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;
 }
Beispiel #2
0
 /**
  * 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());
     }
 }
Beispiel #3
0
 /**
  * 逐一统计所有需要统计的脚本信息
  * 脚本执行方法: 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;
 }
Beispiel #4
0
 /**
  * 复制插件集合默认数据
  *
  * @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;
     }
 }
Beispiel #5
0
 /**
  * 处理数据中的关联数据
  */
 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');
     }
 }
Beispiel #6
0
 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;
 }
Beispiel #7
0
 /**
  * 批量保存字段修改
  *
  * @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, '更新字段属性成功');
 }
Beispiel #8
0
 /**
  * 导出数据
  */
 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;
     }
 }
Beispiel #9
0
 /**
  * 设定集合名称,请在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;
 }