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; }
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; }
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(); } }