Jump to content
  • 0
Crowic

Precyzyjne wyszukiwanie frazy - 1.7.2.0

Question

Witam,

 

mam problem z wyszukiwarką produktów w wersji 1.7.2.0, mianowicie kiedy chcę wyszukać nazwę produktu składającą się z 3 wyrazów np.: "Spotkanie nad morzem", wyszukuje mi również produkty które zawierają pojedynczy wyraz w swojej nazwie, czyli "spotkanie", "nad", "morzem".

 

Moje pytanie czy da się zmanipulować wyszukiwarką tak, aby przy całej frazie wyszukiwała dokładnie pojedynczy produkt, a nie całą masę?

 

Link do strony, gdzie można zauważyć problem: https://pandecor.pl

 

:)

Share this post


Link to post
Share on other sites

15 answers to this question

Recommended Posts

  • 0

Jężeli ciężko naprawić proces wyszukiwania, to może ktoś się orientuje gdzie można byłoby podmienić pliki odpowiadające za wyszukiwanie np z wersji 1.6 :)

 

Z góry dziękuje za pomoc!

Share this post


Link to post
Share on other sites
  • 0

Mam ten sam problem - wyszukiwarka w tej wersji działa trochę dziwnie, zawsze znajduje mi za dużą ilość produktów. Próbowałem już ustawić wagę, tak żeby szukało tylko po nazwie produktów i nie po części słowa, ale dalej wyszukuje prawie wszystkie produkty, które mają część słowa. Oczywiście indeks cały przebudowany.

 

Przykład:

Produkt nazywa się: Dywan nr 43 oliwka 160x220cm

 

Wpisując w wyszukiwarkę znajduje mi takie produkty jak: Chodnik Dywanowy Weltom Welen Trio Stare Złoto 80cm

 

Ogólnie znajduje 1399 pozycji... 

Edited by ufiartist (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Bardzo dziękuje za pomoc :)

Wszystko działa idealnie.

 

Faktycznie, przekopiowałem funkcję "find" z pliku Search.php z wersji 1.6.1.9 i wszystko działa jak marzenie.

 

Pozdrawiam!

Share this post


Link to post
Share on other sites
  • 0

Potwierdzam:)

wyszukiwarka 1.7.2.4 po podmianie funkcji find na tą z 1.6 działa dokładnie tak jak potrzeba...

nie mam pojęcia jak developerzy zaprojektowali tą funkcję w 1.7... ale to był jakiś wyszukiwarkowy koszmar :)

Share this post


Link to post
Share on other sites
  • 0

Do folderu classess wgraj oryginalny plik. Przekopiuj go następnie do folderu /override/classes  i podmień funkcje Find na: 

 public static function find($id_lang, $expr, $page_number = 1, $page_size = 1, $order_by = 'position',
        $order_way = 'desc', $ajax = false, $use_cookie = true, Context $context = null)
    {
        if (!$context) {
            $context = Context::getContext();
        }
        $db = Db::getInstance(_PS_USE_SQL_SLAVE_);

        // TODO : smart page management
        if ($page_number < 1) {
            $page_number = 1;
        }
        if ($page_size < 1) {
            $page_size = 1;
        }

        if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)) {
            return false;
        }

        $intersect_array = array();
        $score_array = array();
        $words = explode(' ', Search::sanitize($expr, $id_lang, false, $context->language->iso_code));

        foreach ($words as $key => $word) {
            if (!empty($word) && strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN')) {
                $word = str_replace(array('%', '_'), array('\\%', '\\_'), $word);
                $start_search = Configuration::get('PS_SEARCH_START') ? '%': '';
                $end_search = Configuration::get('PS_SEARCH_END') ? '': '%';

                $intersect_array[] = 'SELECT DISTINCT si.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.id_shop = '.$context->shop->id.'
                        AND sw.word LIKE
                    '.($word[0] == '-'
                        ? ' \''.$start_search.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).$end_search.'\''
                        : ' \''.$start_search.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).$end_search.'\''
                    );

                if ($word[0] != '-') {
                    $score_array[] = 'sw.word LIKE \''.$start_search.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).$end_search.'\'';
                }
            } else {
                unset($words[$key]);
            }
        }

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

        $score = '';
        if (is_array($score_array) && !empty($score_array)) {
            $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 sw.id_shop = '.$context->shop->id.'
                    AND si.id_product = p.id_product
                    AND ('.implode(' OR ', $score_array).')                 
            ) position';
        }

        $sql_groups = '';
        if (Group::isFeatureActive()) {
            $groups = FrontController::getCurrentCustomerGroups();
            $sql_groups = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
        }

        $results = $db->executeS('
        SELECT DISTINCT cp.`id_product`
        FROM `'._DB_PREFIX_.'category_product` cp
        '.(Group::isFeatureActive() ? 'INNER JOIN `'._DB_PREFIX_.'category_group` cg 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`
        '.Shop::addSqlAssociation('product', 'p', false).'
        WHERE c.`active` = 1
        AND product_shop.`active` = 1
        AND product_shop.`visibility` IN ("both", "search")
        AND product_shop.indexed = 1
        '.$sql_groups, true, false);

        
        $eligible_products = array();
        foreach ($results as $row)
            $eligible_products[] = $row['id_product'];
        foreach ($intersect_array as $query)
        {
            $eligible_products2 = array();
            foreach ($db->executeS($query) as $row)
                $eligible_products2[] = $row['id_product'];

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

        $eligible_products = array_unique($eligible_products);

        $product_pool = '';
        foreach ($eligible_products as $id_product) {
            if ($id_product) {
                $product_pool .= (int)$id_product.',';
            }
        }
        if (empty($product_pool)) {
            return ($ajax ? array() : array('total' => 0, 'result' => array()));
        }
        $product_pool = ((strpos($product_pool, ',') === false) ? (' = '.(int)$product_pool.' ') : (' IN ('.rtrim($product_pool, ',').') '));

        if ($ajax) {
            $sql = '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.Shop::addSqlRestrictionOnLang('pl').'
                    )
                    '.Shop::addSqlAssociation('product', 'p').'
                    INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (
                        product_shop.`id_category_default` = cl.`id_category`
                        AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').'
                    )
                    WHERE p.`id_product` '.$product_pool.'
                    ORDER BY position DESC LIMIT 10';
            return $db->executeS($sql, true, false);
        }

        if (strpos($order_by, '.') > 0) {
            $order_by = explode('.', $order_by);
            $order_by = pSQL($order_by[0]).'.`'.pSQL($order_by[1]).'`';
        }
        $alias = '';
        if ($order_by == 'price') {
            $alias = 'product_shop.';
        } elseif (in_array($order_by, array('date_upd', 'date_add'))) {
            $alias = 'p.';
        }
        $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity,
                pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
             image_shop.`id_image` id_image, il.`legend`, m.`name` manufacturer_name '.$score.',
                DATEDIFF(
                    p.`date_add`,
                    DATE_SUB(
                        "'.date('Y-m-d').' 00:00:00",
                        INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY
                    )
                ) > 0 new'.(Combination::isFeatureActive() ? ', product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, IFNULL(product_attribute_shop.`id_product_attribute`,0) id_product_attribute' : '').'
                FROM '._DB_PREFIX_.'product p
                '.Shop::addSqlAssociation('product', 'p').'
                INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
                    p.`id_product` = pl.`id_product`
                    AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
                )
                '.(Combination::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop
                ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.')':'').'
                '.Product::sqlStock('p', 0).'
                LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
                LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
                    ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')
                LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
                WHERE p.`id_product` '.$product_pool.'
                GROUP BY product_shop.id_product
                '.($order_by ? 'ORDER BY  '.$alias.$order_by : '').($order_way ? ' '.$order_way : '').'
                LIMIT '.(int)(($page_number - 1) * $page_size).','.(int)$page_size;
        $result = $db->executeS($sql, true, false);

        $sql = 'SELECT COUNT(*)
                FROM '._DB_PREFIX_.'product p
                '.Shop::addSqlAssociation('product', 'p').'
                INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
                    p.`id_product` = pl.`id_product`
                    AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
                )
                LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
                WHERE p.`id_product` '.$product_pool;
        $total = $db->getValue($sql, false);

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

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

 

chyba, że masz już tam taki plik (np. z jakiegoś modułu) to w tym pliku podmień. 

Edited by ufiartist (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Witam

Czy zna ktoś sposób na rozwiązanie tego problemu w preście 1.7.3.2?

Share this post


Link to post
Share on other sites
  • 0

Ponawiam pytanie. Czy zna ktoś sposób na rozwiązanie tego problemu w najnowszej preście?

Share this post


Link to post
Share on other sites
  • 0

Technicznie rzecz biorąc to pod 1.6 udało mi się to napisać i to w całkiem łatwy sposób, ale na 1.7 nie siedzę. Wystarczy tylko zmodyfikować zapytanie by wyszukiwało po name z tabeli product_lang.

Share this post


Link to post
Share on other sites
  • 0

Znajdzie się jakaś dobra dusza która wytłumaczy jak zmodyfikować wyszukiwarkę?

Share this post


Link to post
Share on other sites
  • 0

Czy najnowsza wersja 1.7.4.0 rozwiązuje problem z wyszukiwarką???

Share this post


Link to post
Share on other sites
  • 0

Wyszukiwarka w prestashop dla złożonych zapytań domyślnie zwraca wszystkie produkty, które można znaleźć na którekolwiek z wpisanych słów.

Opracowałem rozwiązanie tego problemu - moduł SearchX [szczegółowy opis modułu]

Share this post


Link to post
Share on other sites
  • 0

Hej, czy możecie pomóc w tym problemie przy Preście 1.7.5.1 ?  Męczę się i męczę, może ktoś wie jak to ogarnąć? 

Tak krok po kroku, dla laika ;) 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More