Exemple #1
0
 public function initializeData()
 {
     $dbConnection = Main\HttpApplication::getConnection();
     $res = Location\LocationTable::getList(array('select' => array('ID', 'TYPE_ID', 'DEPTH_LEVEL', 'SORT'), 'order' => array('LEFT_MARGIN' => 'asc'), 'limit' => self::STEP_SIZE, 'offset' => $this->procData['OFFSET']));
     $this->procData['TYPE_SORT'] = $this->rarefact($this->procData['TYPE_SORT']);
     $cnt = 0;
     while ($item = $res->fetch()) {
         // tmp!!!!
         //$name = Location\Name\LocationTable::getList(array('select' => array('NAME'), 'filter' => array('=LOCATION_ID' => $item['ID'], '=LANGUAGE_ID' => 'ru')))->fetch();
         if ($item['DEPTH_LEVEL'] < $this->procData['DEPTH']) {
             $newPC = array();
             foreach ($this->procData['PATH'] as $dl => $id) {
                 if ($dl >= $item['DEPTH_LEVEL']) {
                     break;
                 }
                 $newPC[$dl] = $id;
             }
             $this->procData['PATH'] = $newPC;
         }
         $this->procData['PATH'][$item['DEPTH_LEVEL']] = array('TYPE' => $item['TYPE_ID'], 'ID' => $item['ID']);
         if (is_array($this->procData['ALLOWED_TYPES']) && in_array($item['TYPE_ID'], $this->procData['ALLOWED_TYPES'])) {
             $data = array('LOCATION_ID' => $item['ID'], 'RELEVANCY' => $this->procData['TYPE_SORT'][$item['TYPE_ID']] + $item['SORT']);
             $wordsAdded = array();
             /*
             _dump_r('############################');
             _dump_r('LOCATION: '.$name['NAME']);
             _dump_r('TYPE RELEVANCY: '.$data['RELEVANCY']);
             _dump_r('PATH:');
             _dump_r($this->procData['PATH']);
             */
             $this->procData['DEPTH'] = $item['DEPTH_LEVEL'];
             // pre-load missing words
             $wordCount = 0;
             foreach ($this->procData['PATH'] as &$pathItem) {
                 if (!isset($pathItem['WORDS'])) {
                     $sql = "\n\t\t\t\t\t\t\tselect WS.POSITION from " . WordTable::getTableNameWord2Location() . " WL\n\t\t\t\t\t\t\t\tinner join " . WordTable::getTableName() . " WS on WL.WORD_ID = WS.ID\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tWL.LOCATION_ID = '" . intval($pathItem['ID']) . "'\n\t\t\t\t\t\t";
                     $wordRes = $dbConnection->query($sql);
                     $pathItem['WORDS'] = array();
                     while ($wordItem = $wordRes->fetch()) {
                         $pathItem['WORDS'][] = $wordItem['POSITION'];
                     }
                     $pathItem['WORDS'] = array_unique($pathItem['WORDS']);
                 }
                 $wordCount += count($pathItem['WORDS']);
             }
             // count words
             //_dump_r('Words total: '.$wordCount);
             $wOffset = 0;
             foreach ($this->procData['PATH'] as &$pathItem) {
                 foreach ($pathItem['WORDS'] as $i => $position) {
                     $wordWeight = $wordCount - $wOffset;
                     $tmpData = $data;
                     $tmpData['RELEVANCY'] += $wordWeight;
                     //_dump_r('	Word relevancy: '.$data['RELEVANCY'].' ==>> '.$tmpData['RELEVANCY']);
                     if (!isset($wordsAdded[$position])) {
                         $this->indexInserter->insert(array_merge(array('POSITION' => $position), $tmpData));
                         $wordsAdded[$position] = true;
                     }
                     $wOffset++;
                 }
             }
             unset($pathItem);
         }
         $cnt++;
     }
     $this->indexInserter->flush();
     $this->procData['OFFSET'] += self::STEP_SIZE;
     return !$cnt;
 }
Exemple #2
0
 public function initializeData()
 {
     $dbConnection = Main\HttpApplication::getConnection();
     $res = Location\LocationTable::getList(array('select' => array('ID', 'TYPE_ID', 'DEPTH_LEVEL', 'SORT'), 'order' => array('LEFT_MARGIN' => 'asc'), 'limit' => self::STEP_SIZE, 'offset' => $this->procData['OFFSET']));
     $cnt = 0;
     while ($item = $res->fetch()) {
         $name = Location\Name\LocationTable::getList(array('select' => array('NAME'), 'filter' => array('=LOCATION_ID' => $item['ID'], '=LANGUAGE_ID' => 'ru')))->fetch();
         if ($item['DEPTH_LEVEL'] < $this->procData['DEPTH']) {
             $newPC = array();
             foreach ($this->procData['PATH'] as $dl => $id) {
                 if ($dl >= $item['DEPTH_LEVEL']) {
                     break;
                 }
                 $newPC[$dl] = $id;
             }
             $this->procData['PATH'] = $newPC;
         }
         $this->procData['PATH'][$item['DEPTH_LEVEL']] = array('TYPE' => $item['TYPE_ID'], 'ID' => $item['ID']);
         $this->procData['DEPTH'] = $item['DEPTH_LEVEL'];
         if (is_array($this->procData['ALLOWED_TYPES']) && in_array($item['TYPE_ID'], $this->procData['ALLOWED_TYPES'])) {
             $data = array('LOCATION_ID' => $item['ID'], 'RELEVANCY' => $this->procData['TYPE_SORT'][$item['TYPE_ID']]);
             $wordsAdded = array();
             $k = 1;
             foreach ($this->procData['PATH'] as &$pathItem) {
                 if (!isset($pathItem['WORDS'])) {
                     $sql = "\n\t\t\t\t\t\t\tselect WS.POSITION from " . WordTable::getTableNameWord2Location() . " WL\n\t\t\t\t\t\t\t\tinner join " . WordTable::getTableName() . " WS on WL.WORD_ID = WS.ID\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tWL.LOCATION_ID = '" . intval($pathItem['ID']) . "'\n\t\t\t\t\t\t";
                     $wordRes = $dbConnection->query($sql);
                     $pathItem['WORDS'] = array();
                     while ($wordItem = $wordRes->fetch()) {
                         $pathItem['WORDS'][] = $wordItem['POSITION'];
                     }
                     $pathItem['WORDS'] = array_unique($pathItem['WORDS']);
                 }
                 foreach ($pathItem['WORDS'] as $position) {
                     if (!isset($wordsAdded[$position])) {
                         $this->indexInserter->insert(array_merge(array('POSITION' => $position), $data));
                         $wordsAdded[$position] = true;
                     }
                 }
             }
             unset($pathItem);
         }
         $cnt++;
     }
     $this->indexInserter->flush();
     $this->procData['OFFSET'] += self::STEP_SIZE;
     return !$cnt;
 }
Exemple #3
0
 protected static function findUsingIndex($parameters)
 {
     $query = array();
     $dbConnection = Main\HttpApplication::getConnection();
     $dbHelper = Main\HttpApplication::getConnection()->getSqlHelper();
     $filter = static::parseFilter($parameters['filter']);
     $filterByPhrase = isset($filter['PHRASE']) && strlen($filter['PHRASE']['VALUE']);
     if ($filterByPhrase) {
         $bounds = WordTable::getBoundsForPhrase($filter['PHRASE']['VALUE']);
         $firstBound = array_shift($bounds);
         $k = 0;
         foreach ($bounds as $bound) {
             $query['JOIN'][] = " inner join " . ChainTable::getTableName() . " A" . $k . " on A.LOCATION_ID = A" . $k . ".LOCATION_ID and (\n\n\t\t\t\t\t" . ($bound['INF'] == $bound['SUP'] ? " A" . $k . ".POSITION = '" . $bound['INF'] . "'" : " A" . $k . ".POSITION >= '" . $bound['INF'] . "' and A" . $k . ".POSITION <= '" . $bound['SUP'] . "'") . "\n\t\t\t\t)";
             $k++;
         }
         $query['WHERE'][] = $firstBound['INF'] == $firstBound['SUP'] ? " A.POSITION = '" . $firstBound['INF'] . "'" : " A.POSITION >= '" . $firstBound['INF'] . "' and A.POSITION <= '" . $firstBound['SUP'] . "'";
         $mainTableJoinCondition = 'A.LOCATION_ID';
     } else {
         $mainTableJoinCondition = 'L.ID';
     }
     // site link search
     if (strlen($filter['SITE_ID']['VALUE']) && SiteLinkTable::checkTableExists()) {
         $query['JOIN'][] = "inner join " . SiteLinkTable::getTableName() . " SL on SL.LOCATION_ID = " . $mainTableJoinCondition . " and SL.SITE_ID = '" . $dbHelper->forSql($filter['SITE_ID']['VALUE']) . "'";
     }
     // process filter and select statements
     // at least, we support here basic field selection and filtration + NAME.NAME and NAME.LANGUAGE_ID
     $map = Location\LocationTable::getMap();
     $nameRequired = false;
     $locationRequred = false;
     if (is_array($parameters['select'])) {
         foreach ($parameters['select'] as $alias => $field) {
             if ($field == 'NAME.NAME' || $field == 'NAME.LANGUAGE_ID') {
                 $nameRequired = true;
                 continue;
             }
             if (!isset($map[$field]) || !in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean')) || isset($map[$field]['expression'])) {
                 unset($parameters['select'][$alias]);
             }
             $locationRequred = true;
         }
     }
     foreach ($filter as $field => $params) {
         if ($field == 'NAME.NAME' || $field == 'NAME.LANGUAGE_ID') {
             $nameRequired = true;
             continue;
         }
         if (!isset($map[$field]) || !in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean')) || isset($map[$field]['expression'])) {
             unset($filter[$field]);
         }
         $locationRequred = true;
     }
     // data join, only if extended select specified
     if ($locationRequred && $filterByPhrase) {
         $query['JOIN'][] = "inner join " . Location\LocationTable::getTableName() . " L on A.LOCATION_ID = L.ID";
     }
     if ($nameRequired) {
         $query['JOIN'][] = "inner join " . Location\Name\LocationTable::getTableName() . " NAME on NAME.LOCATION_ID = " . $mainTableJoinCondition;
     }
     //  and N.LANGUAGE_ID = 'ru'
     // making select
     if (is_array($parameters['select'])) {
         $select = array();
         foreach ($parameters['select'] as $alias => $field) {
             if ($field != 'NAME.NAME' && $field != 'NAME.LANGUAGE_ID') {
                 $field = 'L.' . $dbHelper->forSql($field);
             }
             if ((string) $alias === (string) intval($alias)) {
                 $select[] = $field;
             } else {
                 $select[] = $field . ' as ' . $dbHelper->forSql($alias);
             }
         }
         $sqlSelect = implode(', ', $select);
     } else {
         $sqlSelect = $mainTableJoinCondition . ' as ID';
     }
     // making filter
     foreach ($filter as $field => $params) {
         if ($field != 'NAME.NAME' && $field != 'NAME.LANGUAGE_ID') {
             $field = 'L.' . $dbHelper->forSql($field);
         }
         $query['WHERE'][] = $field . ' ' . $params['OP'] . " '" . $dbHelper->forSql($params['VALUE']) . "'";
     }
     if ($filterByPhrase) {
         $sql = "\n\t\t\t\tselect " . ($dbConnection->getType() == 'oracle' ? '' : 'distinct') . " \n\t\t\t\t\t" . $sqlSelect . (\Bitrix\Sale\Location\DB\Helper::needSelectFieldsInOrderByWhenDistinct() ? ', A.RELEVANCY' : '') . "\n\n\t\t\t\tfrom " . ChainTable::getTableName() . " A\n\n\t\t\t\t\t" . implode(' ', $query['JOIN']) . "\n\n\t\t\t\t" . (count($query['WHERE']) ? 'where ' : '') . implode(' and ', $query['WHERE']) . "\n\n\t\t\t\torder by A.RELEVANCY asc\n\t\t\t";
     } else {
         $sql = "\n\n\t\t\t\tselect \n\t\t\t\t\t" . $sqlSelect . "\n\n\t\t\t\tfrom " . Location\LocationTable::getTableName() . " L\n\n\t\t\t\t\t" . implode(' ', $query['JOIN']) . "\n\n\t\t\t\t" . (count($query['WHERE']) ? 'where ' : '') . implode(' and ', $query['WHERE']) . "\n\t\t\t";
     }
     $offset = intval($parameters['offset']);
     $limit = intval($parameters['limit']);
     if ($limit) {
         $sql = $dbHelper->getTopSql($sql, $limit, $offset);
     }
     $res = $dbConnection->query($sql);
     return $res;
 }
 protected function stageRestoreDBIndexes()
 {
     $step = $this->getStep();
     if ($step == 0) {
         WordTable::createIndex();
     } elseif ($step == 1) {
         ChainTable::createIndex();
     } elseif ($step == 2) {
         SiteLinkTable::createIndex();
     }
     if ($step >= 2) {
         $this->nextStage();
     } else {
         $this->nextStep();
     }
 }