Post by kingzjeans » Fri Mar 15, 2019 9:49 pm

Hi,

I want to be able to be able to display related search terms on a search result's page. My website runs on opencart 3.0.2
Example: I have this page: https://www.kingzjeans.ro/index.php?rou ... ur%20lasat
The search term here is this: PANTALONI BARBATI CU TUR LASAT

I want to display at the bottom of this page, underneath the results (the products) a list of let's say 10 related (similar) search terms already existing in the database like: pantaloni cu tur lasat, pantaloni cu tur, pantaloni barbati

How can I do this? I searched everywhere and there is nothing like this. I want to do this as it is a very good method to do internal linking between the search terms pages.

I was thinking of a query of this sort:
$sql = "SELECT *, MATCH keyword AGAINST ('%$search%' IN BOOLEAN MODE) AS relevance FROM oc_customer_search
WHERE MATCH keyword AGAINST ('%$search%' IN BOOLEAN MODE)
HAVING Relevance > 0.2 Order by Relevance
DESC LIMIT 8";
$result = mysqli_query($mysqli, $sql);

I don't know how to do this automatically... Any help is much appreciated :)

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by thekrotek » Fri Mar 15, 2019 11:51 pm

It's kinda hard to do automatically, because relevance criteria are not clear. I'm afraid, you will have to do it manually.

Professional OpenCart extensions, support and custom work.
Contact me via email or Skype by support@thekrotek.com


User avatar
Expert Member

Posts

Joined
Sun Jul 03, 2016 12:24 am


Post by joakimcom » Sat Mar 16, 2019 1:22 am

You could use one of, or a combination of these functions to look for similar terms, although these are better for individual words than for complete text:

http://php.net/manual/en/function.levenshtein.php
http://php.net/manual/en/function.similar-text.php

They allow comparison of words / strings with similar structure and would allow you to check if a string is 'similar' or not in your searches table.

Another 'lighter' option is to gradually split the string on space, and perform a search for each sub-string.

$search_term= split(' ', $searchterm);
$mysql_query = 'SELECT * FROM oc_customer_search WHERE';
foreach($search_term as $term) {
$mysql_query .= "%$term% OR";
}
substr($mysql_query , 0, -2);
$result = mysqli_query($mysqli, $mysql_query );

Untested code, but should get the idea.

This would allow for quite a bit of control in adjusting how you pick your relevant terms.

Your approach in MySQL is quite nice too =)

Newbie

Posts

Joined
Sat Mar 16, 2019 12:48 am


Post by straightlight » Sat Mar 16, 2019 4:27 am

The relevance, in your case, is already included in the v3.0.3.1 called: product variant where each of these variants are associated with product options. The above reply is correct , however. It would, indeed, require larger coding to accomplish this objective.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by letxobnav » Sat Mar 16, 2019 8:16 am

you could however easily breakup the words of the original search term and do a query for additional search terms already logged that are "like" a variation of those words and display those "search term links" if found.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Sat Mar 16, 2019 8:44 am

you could even already show the products of alternative searches.

say the search term is "word1 word2 word3"
if that has no results, do the search like "word1 word2"
if that has no results, do the search like "word1"

or use your logged searches as such.

and say "you searched for ..., showing results for ...."

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by kingzjeans » Mon Mar 18, 2019 6:50 pm

The idea is not the code (php query) but the actual way to have this displayed at the bottom of a search result page... I don't know how to implement the php code in a twig file... I searched the internet and I saw that you can't include a php file inside a twig file...

So, how should I do that without breaking the code of the search.twig file?

I am not concerned about the query itself but more on the way to actually include the results...

Basically what I need is something like this:
Let's say I am on a search result page like this: https://www.kingzjeans.ro/index.php?rou ... aca%20alba
The query used here is: geaca alba
The php file would search inside the already inserted keywords in the database for something like geaca or alba or both...

But that is not what concerns me but the actual way to implement this feature...

Thank you all for being so kind and answering to my topic :D

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by kingzjeans » Mon Mar 18, 2019 6:59 pm

Hi Joakim,

Thank you for taking the time to answer but my concern is not about the query itself, that is something I will deal with later on. The only thing that I don't know, as I am not too opencart savy, is the actual way to have this related search terms and have them displayed on a search result page... I have posted an answer at the end of this topic...

Where should I put the php code and how to make it show in the search.twig file ? That is what I don't know...
joakimcom wrote:
Sat Mar 16, 2019 1:22 am
You could use one of, or a combination of these functions to look for similar terms, although these are better for individual words than for complete text:

http://php.net/manual/en/function.levenshtein.php
http://php.net/manual/en/function.similar-text.php

They allow comparison of words / strings with similar structure and would allow you to check if a string is 'similar' or not in your searches table.

Another 'lighter' option is to gradually split the string on space, and perform a search for each sub-string.

$search_term= split(' ', $searchterm);
$mysql_query = 'SELECT * FROM oc_customer_search WHERE';
foreach($search_term as $term) {
$mysql_query .= "%$term% OR";
}
substr($mysql_query , 0, -2);
$result = mysqli_query($mysqli, $mysql_query );

Untested code, but should get the idea.

This would allow for quite a bit of control in adjusting how you pick your relevant terms.

Your approach in MySQL is quite nice too =)

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by OSWorX » Mon Mar 18, 2019 7:53 pm

kingzjeans wrote:
Mon Mar 18, 2019 6:50 pm
So, how should I do that without breaking the code of the search.twig file?

I am not concerned about the query itself but more on the way to actually include the results...
You have already done all inside the model and controller file.
As last step build the output also inside the controller.

Either by assigning these values to a new (sub) template and add this code to the already existing output.
Or generate the output without a template and add these lines to the output.

This way you do not have to edit any template.

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by kingzjeans » Mon Mar 18, 2019 10:36 pm

That's the thing... I didn't do anything of those... It would really help me if you or anybody else would provide me a controller, a model and a way to output the code... This is what I don't know how to do :(

I will edit the php code but I need the exact steps of what I should do :( I don't know too much about opencart and how it works...

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by letxobnav » Wed Mar 20, 2019 2:05 pm

well, I do a little similar but only if no results are found and I use a misspelled keyword table (which keeps growing)

So, in the search controller, if I find nothing on the search keywords, I check if one or more of the keywords are in my "misspelled" table.
If they are, I pass the search link with the correct words to the view and display, "did you mean"...

Only if I cannot find any results as I am not in the spelling correction business.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by kingzjeans » Wed Mar 20, 2019 6:53 pm

@letxobnav : can you please pm to me the files you use for this mod? It would really help me :(

You can also send them on my email contact@kingzjeans.ro

I would be really thankful for that :) as I really don't know how to do what you already say you managed to do... This thing is incredibly useful SEO wise for internal linking between search terms pages... as they don't receive internal backlinks from elsewhere... That is why I want to do that...

My website is running on opencart 3.0.2.0

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by joakimcom » Thu Mar 21, 2019 6:09 pm

Keeping reply here, but feel free to email me if you would like further clarification with screenshots =)

Basically, you would perform your PHP logic in the opencart/upload/catalog/controller/product/search.php file in this case (although a mod is a better option than adjusting the core, but google that separately)

When you perform a search in OpenCart you hit the following URL:

https://demo.opencart.com/index.php?rou ... rch=iphone

The interesting part is the route=product/search which tells you that you need to look at the controller folder product, and the file search.php.

When that URL is hit, the index function in that file is accessed.

In this index file you will have a lot of $data['values'] statements, anything inside the $data array gets passed to a template file, and is accessed there via the 'values' parameter

e.g in search.php

$data['search'] = 'Some search term';
$this->response->setOutput($this->load->view('product/search', $data));

This is passed to the file opencart/upload/catalog/view/theme/<your theme here, default or other theme if installed>/template/product/search.twig
(see product/search in the setOutput function)

Any data set in $data e.g $data['search'] is available in the twig file as: {{ search }}

So in your controller (product/search.php) perform whatever logic you require to get your desired search terms/output data.

Add this data to $data array e.g $data['my_custom_search_terms'] = 'other search terms'

Then print this information in the twig file as {{ my_custom_search_terms }}

You will also need to add appropriate html wrapping 'a hrefs' etc to make the clickable links, but that is the basic flow of information, and how you get from php / query information, to your html output =)

Human


Newbie

Posts

Joined
Sat Mar 16, 2019 12:48 am


Post by letxobnav » Fri Mar 22, 2019 9:53 am

Well, my solution for misspelled words is not the same as what you are seeking but it might give you the idea.
Still.

I have a table with fields word, replacement and language_id and primary key on word and language_id.
I add (manual) misspelled words into that table if I find that people searched with those before, I also added plurals to that table that if you search for "bracelets" I do not try to remove or ignore the "s" but I simply treat that as a misspelled word and will suggest "bracelet" instead.

I have a new function in catalog/model/catalog/search.php
This will check each word in the search keywords for possible misspelling and correct them if it finds one.

Code: Select all

	public function getSearchSuggestion($keywords,$language_id = 1) {
		$parts = explode(' ',$keywords);
		$new_parts = array();
		foreach($parts as $part) {
			$query = $this->db->query("select sws_replacement from searchword_swap where sws_word = '".$this->db->escape($part)."' and language_id = '".$language_id."'");
			$result = $query->row['sws_replacement'];
			if ($result) {
				$new_parts[] = $result;
			} else {
				$new_parts[] = $part;
			}
		}
		$suggestion = implode(' ',$new_parts);
		if ($suggestion != $keywords) {
			return $suggestion;
		} else {
			return false;
		}
	}
in catalog/controller/product/search.php
I add the following code to call that function when the original search does not yield results.

Code: Select all

			$search_replacement = false;
			if (!$results) {
					// misspelled words perhaps
					$correction = $this->model_catalog_search->getSearchSuggestion($search,$this->config->get('config_language_id'));
					if ($correction) $search_replacement = $correction;
			}
then after the creation of the normal page url I add:

Code: Select all

			$repl_url = '';
			if ($search_replacement) {
				$repl_term = urlencode(html_entity_decode($search_replacement, ENT_QUOTES, 'UTF-8'));
				$repl_url = str_replace($search_term,$repl_term,$url);
			}
to create the additional url with the corrected search term.
then before the view is called just after

Code: Select all

$data['href'] = $this->url->link('product/search', $url);
I add that replacement url

Code: Select all

$data['repl_url'] = $this->url->link('product/search', $repl_url);
then finally in the view catalog/view/theme/default/template/product/search.twig

I simply have:

Code: Select all

<h3>{{ heading_title }}{% if search_replacement %}{{ text_search_instead }} <a href="{{ repl_url }}"><i><strong>{{ search_replacement }}</strong></i></a>?{% endif %}</h3>
which will add the replacement link after the original heading title on the page if there is a replacement link given.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by kingzjeans » Fri Mar 22, 2019 8:58 pm

Jesus, @letxobnav and @joakimcom... you guys are really really awesome!

You took so much of your time just to help me out. This is something one does not see too often!

Thank you from the bottom of my heart for everything! I will keep in consideration everything you wrote and I will try to achieve what I need!

Thank you, thank you, thank you!

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by kingzjeans » Fri Mar 22, 2019 11:03 pm

Based on your help, I have come to the point that I have the related keywords displayed on my search page.

https://www.kingzjeans.ro/index.php?rou ... ur%20lasat

After the pagination, you can find the: Cautari similare: pantaloni tur lasat,tur,pantaloni tur lasat

That array is the related search terms.

The only thing I didn't manage to do is to have a link on each of those search terms. Basically I need to have the search url for each of the words, something like this, in the html output:

Cautari similare: <a href="https://www.kingzjeans.ro/index.php?rou ... >pantaloni tur lasat</a>, <a href="https://www.kingzjeans.ro/index.php?rou ... ur">tur</a>, <a href="https://www.kingzjeans.ro/index.php?rou ... >pantaloni tur lasat</a>

How should I modify the code below that already successfully outputs the array of similar searches?

I have this in my controllers/product/search.php at the very end of the page:

$keywords = $this->request->get['search'];
$parts = explode(' ',$keywords);
foreach($parts as $part) {
$query = $this->db->query("select keyword from oc_customer_search where match keyword against ('%$part%' in boolean mode) order by customer_search_id desc limit 5");
$result = $query->row['keyword'];
if ($result) {
$new_parts[] = $result;
} else {
$new_parts[] = $part;
}
}
$data['href'] = $this->url->link('product/search', $url);
$suggestion = implode(' ',$new_parts);

$data['suggestion'] = implode(',',$new_parts);

$this->response->setOutput($this->load->view('product/search', $data));
}



}

Thank you very much!

Newbie

Posts

Joined
Fri Mar 15, 2019 9:44 pm

Post by letxobnav » Sat Mar 23, 2019 12:45 am

as I understand it, you want to find up to 5 search terms from the oc_customer_search table which match each keyword in your search term.
Then display each of those related search terms.

well, oc_customer_search is not a good table to do that as it has a lot of duplicates, it stores every search term per timestamp with the search parameters and regardless of results.
So maybe try distinct keyword and products > 0

still,

after:

Code: Select all

$keywords = $this->request->get['search'];
$parts = explode(' ',$keywords);
foreach($parts as $part) {
$query = $this->db->query("select keyword from oc_customer_search where match keyword against ('%$part%' in boolean mode) order by customer_search_id desc limit 5");
$result = $query->row['keyword'];
if ($result) {
$new_parts[] = $result;
} else {
$new_parts[] = $part;
}
}
I would put:

Code: Select all

// remove duplicates
$new_parts = array_unique($new_parts);
// create the link array
foreach ($new_parts as $part) {
	$data['related_searches'][] = array(
	'text'  => $part,
	'href'  => $this->url->link('product/search', '&search=' . $part)
	);


and in the view:

Code: Select all

	{% if related_searches %}
		{% for related_search in related_searches %}
			<h3><a href="{{ related_search.href }}">{{ related_search.text }}</a></h3>
		{% endfor %}
	{% endif %}

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Sat Mar 23, 2019 2:22 pm

Personally I have disabled the use of the customer_search table as it is a disaster in waiting and it is just for reporting.

That table stores every search made with the criteria regardless, great if you work for the NSA or are just a big-data freak.
For an e-commerce shop this is big-data of the stupid kind as there is no store control, it stores everything it is given.

If a bot has the desire, they can perform 100+ searches/sec on your site and that table will record them all.

Besides, even on normal use, who wants to know how many searches were made for a search term and how many products that resulted into per second?

That table should change the date_added field to a date field, add a number_of_searches field and have the primary key set to the all fields except the products and new number_of_searches fields.
Then when a search is made, insert and ON DUPLICATE KEY UPDATE the products field and increase the number_of searches value.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Sat Mar 23, 2019 10:43 pm

One other thing you may want to consider.
People may enter pretty offensive search phrases which are then stored and may then end up showing to other users as alternative searches with your solution.
Perhaps put some filter on those or manually enable individual alternative searches before showing them.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by straightlight » Sun Mar 24, 2019 1:59 am

I did put some thoughts about this feature lately. Which is why, one of the alternate solution I migrated from the customer search is with this one where the customer search would rather be useful with: viewtopic.php?f=24&t=210586 . However, I am putting some ideas on combining the results using the same approach as the product quantity with the cart library where no duplicated rows can be found from the same tokens. This will allow the database to optimize the results by dates rather than by having a million results of the same entries either by the same or different users.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON
Who is online

Users browsing this forum: Semrush [Bot] and 520 guests