{"id":152,"date":"2010-11-15T23:36:45","date_gmt":"2010-11-15T22:36:45","guid":{"rendered":"http:\/\/sematext.solr.pl\/?p=152"},"modified":"2020-11-10T23:37:37","modified_gmt":"2020-11-10T22:37:37","slug":"solr-and-autocomplete-part-2","status":"publish","type":"post","link":"https:\/\/solr.pl\/en\/2010\/11\/15\/solr-and-autocomplete-part-2\/","title":{"rendered":"Solr and autocomplete (part 2)"},"content":{"rendered":"<p>In the previous part I showed how the faceting mechanism can be used to achieve the autocomplete functionality. Today I&#8217;ll show you how to use a component called Suggester to implement autocomplete functionality.<\/p>\n\n\n<!--more-->\n\n\n<h3>The begining<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-483\" title=\"Google Autocomplete\" src=\"http:\/\/solr.pl\/wp-content\/uploads\/2010\/10\/google_autocomplete2.png\" alt=\"\" width=\"641\" height=\"159\"><br>\nThere is one thing that you must know &#8211; Suggest component is not available in Solr version 1.4.1 and below. To start using this component you need to download 3_x or trunk version from Lucene\/Solr SVN.<\/p>\n<h3>Configuration<\/h3>\n<p>Before we get into the index configuration we need to define an search component. So let&#8217;s do it:\n<\/p>\n<pre class=\"brush:xml\">&lt;searchComponent name=\"suggest\" class=\"solr.SpellCheckComponent\"&gt;\n &lt;lst name=\"spellchecker\"&gt;\n  &lt;str name=\"name\"&gt;suggest&lt;\/str&gt;\n  &lt;str name=\"classname\"&gt;org.apache.solr.spelling.suggest.Suggester&lt;\/str&gt;\n  &lt;str name=\"lookupImpl\"&gt;org.apache.solr.spelling.suggest.tst.TSTLookup&lt;\/str&gt;\n  &lt;str name=\"field\"&gt;name_autocomplete&lt;\/str&gt;\n &lt;\/lst&gt;\n&lt;\/searchComponent&gt;<\/pre>\n<p>It is worth mentioning that suggest component is based on solr.SpellCheckComponent and that&#8217;s why we can use the above configuration. We have three important attributes in the configuration:<\/p>\n<ul>\n<li><em>name <\/em>&#8211; name of the component.<\/li>\n<li><em>lookupImpl<\/em> &#8211; an object that will handle the search. At this point we have two possibilities to use &#8211; JasperLookup or TSTLookup. This second one characterizes greater efficiency.<\/li>\n<li><em>field<\/em> &#8211; the field on the basis of which suggestions are generated.<\/li>\n<\/ul>\n<p>Now let&#8217;s add the appropriate handler:\n<\/p>\n<pre class=\"brush:xml\">&lt;requestHandler name=\"\/suggest\" class=\"org.apache.solr.handler.component.SearchHandler\"&gt;\n &lt;lst name=\"defaults\"&gt;\n  &lt;str name=\"spellcheck\"&gt;true&lt;\/str&gt;\n  &lt;str name=\"spellcheck.dictionary\"&gt;suggest&lt;\/str&gt;\n  &lt;str name=\"spellcheck.count\"&gt;10&lt;\/str&gt;\n &lt;\/lst&gt;\n &lt;arr name=\"components\"&gt;\n  &lt;str&gt;suggest&lt;\/str&gt;\n &lt;\/arr&gt;\n&lt;\/requestHandler&gt;<\/pre>\n<p>Quite simple configuration, which defines a handler with an additional search component and tell Solr that the maximum number of suggestions returned is 10, this it should use dictionary named suggest (which is actually a Suggest component) which is exactly the same as our defined component.<\/p>\n<h3>Index<\/h3>\n<p>Let us assume that our document consists of three fields: id, name and description. We want to generate suggestions on the field that hold the name of the product. Our index could look like this:\n<\/p>\n<pre class=\"brush:xml\">&lt;field name=\"id\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"false\" required=\"true\"\/&gt;\n&lt;field name=\"name\" type=\"text\" indexed=\"true\" stored=\"true\" multiValued=\"false\" \/&gt;\n&lt;field name=\"name_autocomplete\" type=\"text_auto\" indexed=\"true\" stored=\"true\" multiValued=\"false\" \/&gt;\n&lt;field name=\"description\" type=\"text\" indexed=\"true\" stored=\"true\" multiValued=\"false\" \/&gt;<\/pre>\n<p>In addition, there is the following copy field definition:\n<\/p>\n<pre class=\"brush:xml\">&lt;copyField source=\"name\" dest=\"name_autocomplete\" \/&gt;<\/pre>\n<h3>Suggesting single words<\/h3>\n<p>In order to achieve individual words suggestions text_autocomplete type should be defined as follows:\n<\/p>\n<pre class=\"brush:xml\">&lt;fieldType class=\"solr.TextField\" name=\"text_auto\" positionIncrementGap=\"100\"&gt;\n &lt;analyzer&gt;\n  &lt;tokenizer class=\"solr.WhitespaceTokenizerFactory\"\/&gt;\n  &lt;filter class=\"solr.WordDelimiterFilterFactory\" generateWordParts=\"1\" generateNumberParts=\"1\" catenateWords=\"1\" catenateNumbers=\"1\" catenateAll=\"0\" splitOnCaseChange=\"1\"\/&gt;\n  &lt;filter class=\"solr.LowerCaseFilterFactory\"\/&gt;\n &lt;\/analyzer&gt;\n&lt;\/fieldType&gt;<\/pre>\n<h3>Suggesting phrases<\/h3>\n<p>To implement the entire phrase suggestions our text_autocomplete type should be defined as follows:\n<\/p>\n<pre class=\"brush:xml\">&lt;fieldType class=\"solr.TextField\" name=\"text_auto\"&gt;\n &lt;analyzer&gt;\n  &lt;tokenizer class=\"solr.KeywordTokenizerFactory\"\/&gt;\n  &lt;filter class=\"solr.LowerCaseFilterFactory\"\/&gt;\n &lt;\/analyzer&gt;\n&lt;\/fieldType&gt;<\/pre>\n<p>If you want to use phrases you may want to define your own query converter.<\/p>\n<h3>Dictionary building<\/h3>\n<p>Before we start using the component, we need to build its index. To this send the following command to Solr:\n<\/p>\n<pre class=\"brush:bash\">\/suggest?spellcheck.build=true<\/pre>\n<h3>Queries<\/h3>\n<p>Now we come to use of the component. In order to show how the use the component, I decided suggest whole phrases. The example query could look like that:\n<\/p>\n<pre class=\"brush:bash\">\/suggest?q=har<\/pre>\n<p>After running that query I got the following suggestions:\n<\/p>\n<pre class=\"brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;response&gt;\n &lt;lst name=\"responseHeader\"&gt;\n  &lt;int name=\"status\"&gt;0&lt;\/int&gt;\n  &lt;int name=\"QTime\"&gt;0&lt;\/int&gt;\n &lt;\/lst&gt;\n &lt;lst name=\"spellcheck\"&gt;\n  &lt;lst name=\"suggestions\"&gt;\n   &lt;lst name=\"dys\"&gt;\n    &lt;int name=\"numFound\"&gt;4&lt;\/int&gt;\n    &lt;int name=\"startOffset\"&gt;0&lt;\/int&gt;\n    &lt;int name=\"endOffset\"&gt;3&lt;\/int&gt;\n    &lt;arr name=\"suggestion\"&gt;\n     &lt;str&gt;hard drive&lt;\/str&gt;\n     &lt;str&gt;hard drive samsung&lt;\/str&gt;\n     &lt;str&gt;hard drive seagate&lt;\/str&gt;\n     &lt;str&gt;hard drive toshiba&lt;\/str&gt;\n    &lt;\/arr&gt;\n   &lt;\/lst&gt;\n  &lt;\/lst&gt;\n &lt;\/lst&gt;\n&lt;\/response&gt;<\/pre>\n<h3>The end<\/h3>\n<p>In the next part of the autocomplete functionality I&#8217;ll show how to modify its configuration to use static dictionary into the mechanism and how this can helk you get better suggestions. The last part of the series will be a performance comparison of each method in which I&#8217;ll try to diagnose which method is the fastest one in various situations.<\/p>","protected":false},"excerpt":{"rendered":"<p>In the previous part I showed how the faceting mechanism can be used to achieve the autocomplete functionality. Today I&#8217;ll show you how to use a component called Suggester to implement autocomplete functionality.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[27],"tags":[],"class_list":["post-152","post","type-post","status-publish","format-standard","hentry","category-solr-en"],"_links":{"self":[{"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/posts\/152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/comments?post=152"}],"version-history":[{"count":1,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/posts\/152\/revisions"}],"predecessor-version":[{"id":153,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/posts\/152\/revisions\/153"}],"wp:attachment":[{"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/media?parent=152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/categories?post=152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solr.pl\/en\/wp-json\/wp\/v2\/tags?post=152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}