suntrop Posted August 11, 2017 Posted August 11, 2017 HI all. I recently built a web shop with PW and it works pretty good. I love the simplicity and freedom working with templates and how stuff works and the client loves the back-end. However, the part I am unhappy about is the site search. Beside the API selectors work fine, it seems not be suitable for that kind of search. People search for words, phrases, they mix spaces, hyphens etc., add measurements … so a lot of searches end up in 0 results. I know of the ElasticSearch module and other external things like Sphider, Google CSE, algolia.com … but some are quite complicated and limit my control or bring google's ads on the site So perhaps you have any improvements, ideas how to get a better search engine on my website. Most problems come from spelling issues, singular/plural, hyphenated words/searches. <?php $vars['q'] = $q; $input->whitelist('q', $q); $q = $sanitizer->selectorValue($q); // 1. // Item Number // If there is a number in it that matches a product's numbers, redirect to product directly $q_numeric = preg_replace('/\D/', '', $q); $prodcut_item_number = $pages->get("template=product|product_variation, product_item_number=$q_numeric"); if ( $prodcut_item_number->id && $prodcut_item_number->template == 'product') { $session->redirect($prodcut_item_number->url); die(); } elseif ( $prodcut_item_number->id && $prodcut_item_number->template == 'product_variation') { // variations are saved as sub-pages, but have no public web-page $session->redirect($prodcut_item_number->parent->url); die(); } // 2. // Product title and description // Search the product's title, headline and summary $matches = $pages->find("title|headline|summary~=$q, template=product, limit=50"); // 3. // Categories // If search is a category, append all its products $categories = $pages->find("title%=$q, template=category, limit=10"); if ( count($categories) ) { $category_ids = $categories->each('id'); $category_ids = implode('|', $category_ids); $append_products_from_category = $pages->find("template=product, has_parent={$cat_ids}"); $matches->append($append_products_from_category); } // 4. // Split search phrase // If nothing above matches, try each word separatly if( !count($matches) ) { $q_separate = preg_replace('/\PL/u', ' ', $q); // "Remove" everything but letters $q_separate = preg_split('/\s+/', $q_separate); foreach ($q_separate as $q_word) { if ( $q_word != '' && strlen($q_word) > 4 ) { $append_products_separate = $pages->find("title|headline|summary~=$q_word, template=product, limit=50"); $matches->append($append_products_separate); } } } // PLEASE NOTE – this doesn't come from my production code, but is a current idea I have // There is no highly need of weighting results and order best results on top, because there are just a few products for each keyword :-)
DaveP Posted August 14, 2017 Posted August 14, 2017 Just a few random thoughts... From what I can see, your code is very much heading in a good direction - splitting the task into manageable chunks is IMHO a good way to go. I assume your product names are in German, based on your location. If so, AFAIK you may not be able to use some of the cool stuff available for English like mySQL's SOUNDS LIKE (bit of discussion here). How many products is 'just a few', BTW? One thing to consider is making your product search AJAX powered. Then users can see instantly if they are finding products or otherwise, and you can kind of 'lead' their searching efforts. (One easy way is intercooler.js - see http://intercoolerjs.org/examples/activesearch.html. There is a PW module.) A small thing that I have found useful in the past is to proactively deal with common misspellings - see and the rest of that thread. (YMMV) 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now