질문
public static function indexation($full = false, $id_product = false)
{
$db = Db::getInstance();
$dropIndex = false;
if ($id_product)
$full = false;
if ($full)
{
$db->Execute('TRUNCATE '._DB_PREFIX_.'search_index');
$db->Execute('TRUNCATE '._DB_PREFIX_.'search_word');
$db->Execute('UPDATE '._DB_PREFIX_.'product SET indexed = 0');
$dropIndex = true;
}
else
{
// Do it even if you already know the product id on order to be sure that it exists
$products = $db->ExecuteS('
SELECT id_product
FROM '._DB_PREFIX_.'product
WHERE '.($id_product ? 'id_product = '.(int)$id_product : 'indexed = 0'));
$ids = array();
if ($products)
foreach($products AS $product)
$ids[] = (int)$product['id_product'];
if (sizeof($ids))
$db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
if (count($products) > 2000)
$dropIndex = true;
}
if ($dropIndex)
{
$dropIndex = false;
$result = $db->ExecuteS('SHOW INDEX FROM `'._DB_PREFIX_.'search_index`');
foreach ($result as $row)
if (strtolower($row['Key_name']) == 'primary')
$dropIndex = true;
if ($dropIndex)
$db->Execute('ALTER TABLE '._DB_PREFIX_.'search_index DROP PRIMARY KEY');
$dropIndex = true;
}
//var_dump($db);exit;
// Every fields are weighted according to the configuration in the backend
$weightArray = array(
'pname' => Configuration::get('PS_SEARCH_WEIGHT_PNAME'),
'reference' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
'ean13' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
'upc' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
'description_short' => Configuration::get('PS_SEARCH_WEIGHT_SHORTDESC'),
'description' => Configuration::get('PS_SEARCH_WEIGHT_DESC'),
'cname' => Configuration::get('PS_SEARCH_WEIGHT_CNAME'),
'mname' => Configuration::get('PS_SEARCH_WEIGHT_MNAME'),
'tags' => Configuration::get('PS_SEARCH_WEIGHT_TAG'),
'attributes' => Configuration::get('PS_SEARCH_WEIGHT_ATTRIBUTE'),
'features' => Configuration::get('PS_SEARCH_WEIGHT_FEATURE')
);
// All the product not yet indexed are retrieved
$products = $db->ExecuteS('
SELECT p.id_product, pl.id_lang, pl.name pname, p.reference, p.ean13, p.upc, pl.description_short, pl.description, cl.name cname, m.name mname
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON p.id_product = pl.id_product
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default AND pl.id_lang = cl.id_lang)
LEFT JOIN '._DB_PREFIX_.'manufacturer m ON m.id_manufacturer = p.id_manufacturer
WHERE p.indexed = 0', false);
//var_dump($products);exit;
// Those are kind of global variables required to save the processed data in the database every X occurences, in order to avoid overloading MySQL
$countWords = 0;
$countProducts = 0;
$queryArray3 = array();
$productsArray = array();
// Every indexed words are cached into a PHP array
$wordIdsByWord = array();
$wordIds = Db::getInstance()->ExecuteS('
SELECT sw.id_word, sw.word, id_lang
FROM '._DB_PREFIX_.'search_word sw', false);
$wordIdsByWord = array();
while ($wordId = $db->nextRow($wordIds))
{
if (!isset($wordIdsByWord[$wordId['id_lang']]))
$wordIdsByWord[$wordId['id_lang']] = array();
$wordIdsByWord[$wordId['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word'];
}
// Now each non-indexed product is processed one by one, langage by langage
while ($product = $db->nextRow($products))
{
$product['tags'] = Search::getTags($db, (int)$product['id_product'], (int)$product['id_lang']);
$product['attributes'] = Search::getAttributes($db, (int)$product['id_product'], (int)$product['id_lang']);
$product['features'] = Search::getFeatures($db, (int)$product['id_product'], (int)$product['id_lang']);
// Data must be cleaned of html, bad characters, spaces and anything, then if the resulting words are long enough, they're added to the array
$pArray = array();
//var_dump($product);exit;
foreach ($product AS $key => $value)
if (strncmp($key, 'id_', 2))
{
/********************************************/
//var_dump($value);exit;
//$words = explode(' ',strtolower($value));
$words = explode(' ', Search::sanitize($value, (int)$product['id_lang'], true));
//var_dump($words);exit;
/*********************************************/
foreach ($words AS $word)
if (!empty($word))
{
$word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
if (!isset($pArray[$word]))
$pArray[$word] = 0;
$pArray[$word] += $weightArray[$key];
}
}
// If we find words that need to be indexed, they're added to the word table in the database
if (sizeof($pArray))
{
$list = '';
foreach ($pArray AS $word => $weight)
$list .= '\''.$word.'\',';
$list = rtrim($list, ',');
$queryArray = array();
$queryArray2 = array();
foreach ($pArray AS $word => $weight)
if ($weight AND !isset($wordIdsByWord['_'.$word]))
{
$queryArray[] = '('.(int)$product['id_lang'].',\''.pSQL($word).'\')';
$queryArray2[] = '\''.pSQL($word).'\'';
$wordIdsByWord[$product['id_lang']]['_'.$word] = 0;
}
if (count($queryArray))
{
// The words are inserted...
$db->Execute('
INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, word)
VALUES '.implode(',',$queryArray));
$sql = 'INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, word)
VALUES '.implode(',',$queryArray);
// ...then their IDs are retrieved and added to the cache
$addedWords = $db->ExecuteS('
SELECT sw.id_word, sw.word
FROM '._DB_PREFIX_.'search_word sw
WHERE sw.word IN ('.implode(',', $queryArray2).')
AND sw.id_lang = '.(int)$product['id_lang'].'
LIMIT '.count($queryArray2));
foreach ($addedWords AS $wordId)
$wordIdsByWord[$product['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word'];
}
}
foreach ($pArray AS $word => $weight)
{
if (!$weight)
continue;
if (!isset($wordIdsByWord[$product['id_lang']]['_'.$word]))
continue;
if (!$wordIdsByWord[$product['id_lang']]['_'.$word])
continue;
$queryArray3[] = '('.(int)$product['id_product'].','.(int)$wordIdsByWord[$product['id_lang']]['_'.$word].','.(int)$weight.')';
// Force save every 200 words in order to avoid overloading MySQL
if (++$countWords % 200 == 0)
Search::saveIndex($queryArray3);
}
if (!in_array($product['id_product'], $productsArray))
$productsArray[] = (int)$product['id_product'];
// Force save every 50 products in order to avoid overloading MySQL
if (++$countProducts % 50 == 0)
Search::setProductsAsIndexed($productsArray);
}
// One last save is done at the end in order to save what's left
Search::saveIndex($queryArray3);
Search::setProductsAsIndexed($productsArray);
// If it has been deleted, the index is created again once the indexation is done
if (!$dropIndex)
{
$dropIndex = true;
$result = $db->ExecuteS('SHOW INDEX FROM `'._DB_PREFIX_.'search_index`');
foreach ($result as $row)
if (strtolower($row['Key_name']) == 'primary')
$dropIndex = false;
}
if ($dropIndex)
$db->Execute('ALTER TABLE `'._DB_PREFIX_.'search_index` ADD PRIMARY KEY (`id_word`, `id_product`)');
Configuration::updateValue('PS_NEED_REBUILD_INDEX', 0);
return true;
}
search 입고 부분은 이 방법에서 $words 데이터가 시공이면 다음 방법을 보십시오
public static function sanitize($string, $id_lang, $indexation = false)
{
$string = Tools::strtolower(strip_tags($string));
$string = html_entity_decode($string, ENT_NOQUOTES, 'utf-8');
$string = preg_replace('/(['.PREG_CLASS_NUMBERS.']+)['.PREG_CLASS_PUNCTUATION.']+(?=['.PREG_CLASS_NUMBERS.'])/u', '\1', $string);
/************2014-09-25***************/
//$string = preg_replace('/['.PREG_CLASS_SEARCH_EXCLUDE.']+/u',' ', $string);
$string = str_replace(',', '', $string);
$string = str_replace('.', '', $string);
$string = str_replace('/>', '', $string);
$string = str_replace(':', ' ', $string);
//var_dump($string);exit;
/****************end*********************/
if ($indexation)
$string = preg_replace('/[._-]+/', '', $string);
else
{
$string = preg_replace('/[._]+/', '', $string);
$string = ltrim(preg_replace('/([^ ])-/', '$1', ' '.$string));
$string = preg_replace('/[._]+/', '', $string);
$string = preg_replace('/[^\s]-+/', '', $string);
}
$blacklist = Configuration::get('PS_SEARCH_BLACKLIST', (int)$id_lang);
if (!empty($blacklist))
{
$string = preg_replace('/(?<=\s)('.$blacklist.')(?=\s)/Su', '', $string);
$string = preg_replace('/^('.$blacklist.')(?=\s)/Su', '', $string);
$string = preg_replace('/(?<=\s)('.$blacklist.')$/Su', '', $string);
$string = preg_replace('/^('.$blacklist.')$/Su', '', $string);
}
if (!$indexation)
{
$alias = new Alias(NULL, $string);
if (Validate::isLoadedObject($alias))
$string = $alias->search;
}
if ($indexation)
{
$minWordLen = (int)Configuration::get('PS_SEARCH_MINWORDLEN');
if ($minWordLen > 1)
{
$minWordLen -= 1;
$string = preg_replace('/(?<=\s)[^\s]{1,'.$minWordLen.'}(?=\s)/Su', ' ', $string);
$string = preg_replace('/^[^\s]{1,'.$minWordLen.'}(?=\s)/Su', '', $string);
$string = preg_replace('/(?<=\s)[^\s]{1,'.$minWordLen.'}$/Su', '', $string);
$string = preg_replace('/^[^\s]{1,'.$minWordLen.'}$/Su', '', $string);
}
}
$string = trim(preg_replace('/\s+/', ' ', $string));
return $string;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.