Jump to content

[resolu] Modification fonction recherche sur le champs référence


Recommended Posts

Bonjour,

Sur un PS1.5RC, les produits de mon clients sont bien indexés mais en frontend effectuer une recherche sur la référence 162FE par exemple ne permet pas de trouver la référence 0162FE.

 

Comment corriger ce comportement pour le moins gênant ?

 

Cordialement,

Edited by Semaphore (see edit history)
Link to comment
Share on other sites

Merci de ta réponse mais j'avais bien évidemment tenté une recherche sur le forum sans trouver ma réponse. Te souviens-tu d'un critère ou deux qui pourrait m'aider à affiner ma recherche sur le forum car évidemment sur le mot clef recherche il y a du monde ^^

Link to comment
Share on other sites

je viens de tester, à priori ça marche, par contre si tu as beaucoup de produits je ne suis pas sûre de la rapidité de recherche (mais ça marche) :

Ligne 170 de classes/Search.php

 

foreach ($words AS $key => $word)
if (!empty($word) AND strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
{
$word = str_replace('%', '\\%', $word);
$word = str_replace('_', '\\_', $word);
$intersectArray[] = 'SELECT id_product
FROM '._DB_PREFIX_.'search_word sw
LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word
WHERE sw.id_lang = '.(int)$id_lang.'
AND sw.word LIKE 
'.($word[0] == '-'
? ' \'%'.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).'%\''
: '\'%'.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\''
);
if ($word[0] != '-')
$scoreArray[] = 'sw.word LIKE \'%'.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'';
}
else
unset($words[$key]);

Link to comment
Share on other sites

Débutant juste sur PS (mais dans le Web) je découvre avec grand plaisir : sa communauté, son override de classe (énoorme ca !) et les "petits" trucs à savoir. Et oui coté charge ca va forcément être plus lourd mais je n'ai que 900 ref. Ne me reste plus qu'à créer un override pour tester et je re-viens valider içi.

 

merci encore (au passage j'ai retrouvé le post dont tu parlais je pense)

 

Edit : la modification de la requête fonctionne très bin (normal ^^) et mon premier override c'est fait en 2s ^^

Merci encore et à bientôt car je pense avoir quelques questions au fur et à mesure que je vais gratter dans PS.

Edited by Semaphore (see edit history)
Link to comment
Share on other sites

pour l'override test ça:

 

<?php
class Search extends SearchCore{

public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position', $orderWay = 'desc', $ajax = false, $useCookie = true)
{
global $cookie;
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);

// Only use cookie if id_customer is not present
if ($useCookie)
$id_customer = (int)$cookie->id_customer;
else
$id_customer = 0;

// TODO : smart page management
if ($pageNumber < 1) $pageNumber = 1;
if ($pageSize < 1) $pageSize = 1;

if (!Validate::isOrderBy($orderBy) OR !Validate::isOrderWay($orderWay))
return false;

$intersectArray = array();
$scoreArray = array();
$words = explode(' ', Search::sanitize($expr, (int)$id_lang));

foreach ($words AS $key => $word)
if (!empty($word) AND strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
{
$word = str_replace('%', '\\%', $word);
$word = str_replace('_', '\\_', $word);
$intersectArray[] = 'SELECT id_product
FROM '._DB_PREFIX_.'search_word sw
LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word
WHERE sw.id_lang = '.(int)$id_lang.'
AND sw.word LIKE 
'.($word[0] == '-'
? ' \'%'.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).'%\''
: '\'%'.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\''
);
if ($word[0] != '-')
$scoreArray[] = 'sw.word LIKE \'%'.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'';
}
else
unset($words[$key]);

if (!sizeof($words))
return ($ajax ? array() : array('total' => 0, 'result' => array()));

$score = '';
if (sizeof($scoreArray))
$score = ',(
SELECT SUM(weight)
FROM '._DB_PREFIX_.'search_word sw
LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word
WHERE sw.id_lang = '.(int)$id_lang.'
AND si.id_product = p.id_product
AND ('.implode(' OR ', $scoreArray).')
) position';

$result = $db->ExecuteS('
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
INNER JOIN `'._DB_PREFIX_.'category_product` cp ON cp.`id_category` = cg.`id_category`
INNER JOIN `'._DB_PREFIX_.'category` c ON cp.`id_category` = c.`id_category`
INNER JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product`
WHERE c.`active` = 1 AND p.`active` = 1 AND indexed = 1
AND cg.`id_group` '.(!$id_customer ?  '= 1' : 'IN (
SELECT id_group FROM '._DB_PREFIX_.'customer_group
WHERE id_customer = '.(int)$id_customer.'
)'), false);

$eligibleProducts = array();
while ($row = $db->nextRow($result))
$eligibleProducts[] = $row['id_product'];
foreach ($intersectArray as $query)
{
$result = $db->ExecuteS($query, false);
$eligibleProducts2 = array();
while ($row = $db->nextRow($result))
$eligibleProducts2[] = $row['id_product'];

$eligibleProducts = array_intersect($eligibleProducts, $eligibleProducts2);
if (!count($eligibleProducts))
return ($ajax ? array() : array('total' => 0, 'result' => array()));
}
array_unique($eligibleProducts);

$productPool = '';
foreach ($eligibleProducts AS $id_product)
if ($id_product)
$productPool .= (int)$id_product.',';
if (empty($productPool))
return ($ajax ? array() : array('total' => 0, 'result' => array()));
$productPool = ((strpos($productPool, ',') === false) ? (' = '.(int)$productPool.' ') : (' IN ('.rtrim($productPool, ',').') '));

if ($ajax)
{
return $db->ExecuteS('
SELECT DISTINCT p.id_product, pl.name pname, cl.name cname,
cl.link_rewrite crewrite, pl.link_rewrite prewrite '.$score.'
FROM '._DB_PREFIX_.'product p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.')
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$id_lang.')
WHERE p.`id_product` '.$productPool.'
ORDER BY position DESC LIMIT 10');
}

$queryResults = '
SELECT p.*, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name '.$score.', DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 new
FROM '._DB_PREFIX_.'product p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
                                         AND tr.`id_country` = '.(int)Country::getDefaultCountryId().'
                                             AND tr.`id_state` = 0)
  LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
WHERE p.`id_product` '.$productPool.'
'.($orderBy ? 'ORDER BY  '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize;

$result = $db->ExecuteS($queryResults);
$total = $db->getValue('SELECT COUNT(*)
FROM '._DB_PREFIX_.'product p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
                                         AND tr.`id_country` = '.(int)Country::getDefaultCountryId().'
                                             AND tr.`id_state` = 0)
  LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
WHERE p.`id_product` '.$productPool);

if (!$result)
$resultProperties = false;
else
$resultProperties = Product::getProductsProperties((int)$id_lang, $result);

return array('total' => $total,'result' => $resultProperties);
}
}

Link to comment
Share on other sites

  • 4 months later...

Bonjour à vous deux, vous semblez plutot maitriser le sujet :) alors j'en profite pour vous poser une question : j'ai 260 000 produits et mon indexation (pour le moteur de recherche) n'indexe que 20 000 produits environs.. le CRON ne fait rien, et quand je clique sur "ajouter des produits à mon index" j'ai une très belle page blanche.... je suis sous 1.5.0.17, auriez vous une suggestion sans passer par une mise à jour du CMS ? (d'ailleurs ça sera peut -être pas mieux...)

Merci pour votre aide !

Link to comment
Share on other sites

  • 1 year later...

Bonjour,

 

Mon problème étant proche de celui-ci je me permet de le poster dans le même post.

J'ai des produits dont la référence commence par EX-HK04. Lorsque je tappe EX ou même EX-HK cela ne renvoit rien.
Je n'obtient une réponse qu'à partir de la recherche EX-HK0. Peut-on lui dire de rechcercher dans la référence à partir de moins de caractères.

 

Merci par avance

Edited by Neecolas (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...