Page 1 of 1

How to add autocomplete in the site search?

Posted: Tue Jul 08, 2014 2:47 pm
by gowthamgutha
I would like to add autocomplete in the site search. All that I need is not the JQuery code to do this, but to which URL should I sent the request to.

Should I send request to..

http://localhost:8001/api/v1/catalog/search/products?q=sauce

or is there any other URL?

Is that search powered by Solr or does it directly read from the database? Because, when I am typing the following..

Amrageddon instead of Armageddon which is the starting term of a hot sauce, I am not displayed the correct sauce in the autocomplete?

Thanks in advance. Hope you will reply as soon as possible.

Re: How to add autocomplete in the site search?

Posted: Sat Jul 12, 2014 12:35 pm
by RapidTransit
This is a basic example, and I think Solr on the latest version may have a new Suggest Component

Schema.xml

Code: Select all

//I had to add a custom Solr handler to make the full search title the product Category + Product Name + Product Sku hence the copy field
<field name="suggest_phrase" type="suggest_phrase" indexed="true" stored="false" multiValued="true" />
        <copyField source="fullproductname_t" dest="suggest_phrase" />
        <!-- A general text field that has reasonable, generic cross-language defaults:
            it tokenizes with StandardTokenizer and down cases. -->
        <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
            <analyzer type="index">
                <tokenizer class="solr.StandardTokenizerFactory" />
                <filter class="solr.LowerCaseFilterFactory" />
            </analyzer>
            <analyzer type="query">
                <tokenizer class="solr.StandardTokenizerFactory" />
                <filter class="solr.LowerCaseFilterFactory" />
            </analyzer>
        </fieldType>

        <fieldType name="suggest_phrase" class="solr.TextField" positionIncrementGap="100">
            <analyzer>
                <tokenizer class="solr.KeywordTokenizerFactory" />
                <filter class="solr.LowerCaseFilterFactory" />
            </analyzer>
        </fieldType>


Solr Config

Code: Select all

    <searchComponent name="suggest_phrase" class="solr.SpellCheckComponent" lazy="true">
        <lst name="spellchecker">
            <str name="name">suggest_phrase</str>
            <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
            <str name="lookupImpl">org.apache.solr.spelling.suggest.jaspell.JaspellLookup</str>
            <str name="field">suggest_phrase</str>
            <str name="buildOnCommit">true</str>
            <str name="suggestAnalyzerFieldType">suggest_phrase</str>
        </lst>
    </searchComponent>

    <requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest_phrase">
        <lst name="defaults">
            <str name="spellcheck">true</str>
            <str name="spellcheck.dictionary">suggest_phrase</str>
            <str name="spellcheck.onlyMorePopular">true</str>
            <str name="spellcheck.count">10</str>
            <str name="spellcheck.collate">false</str>
        </lst>
        <arr name="components">
            <str>suggest_phrase</str>
        </arr>
    </requestHandler>

SearchController

Code: Select all

    @RequestMapping(value = "/suggest", produces = "application/json")
    public @ResponseBody List<Map<String, String>> suggest(Model model, HttpServletRequest request, HttpServletResponse response,
                  @RequestParam(value = "q") String q) throws ServletException, IOException, ServiceException, SolrServerException {
        List<Map<String, String>> results = new ArrayList<Map<String, String>>();
        SolrQuery params = new SolrQuery()
            .setRequestHandler("/suggest_phrase");
            params.set("spellcheck", true);
            params.set("spellcheck.q", q);
        QueryResponse queryResponse = SolrContext.getServer().query(params);
        SpellCheckResponse spellCheckResponse = queryResponse.getSpellCheckResponse();
        for(SpellCheckResponse.Suggestion suggestion : spellCheckResponse.getSuggestions()){
            for(String suggestionItem : suggestion.getAlternatives()){
                Map<String, String> suggestionMap = new HashMap<String, String>();
                suggestionMap.put("productName", suggestionItem);
                results.add(suggestionMap);
            }
        }

        return results;
    }


Some javascript using typeahead.js from Twitter

Code: Select all

$(function(){
    var Engine =new Bloodhound({
var token = document.getElementById('searchform').firstElementChild.value
        datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.value); },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote:'search/suggest?csrfToken='+token+'&q=%QUERY',
        limit: 8
    });
    Engine.initialize();
    $('#typeahead').typeahead({
            minLength: 2,
            highlight: true
        },
        {
            source: Engine.ttAdapter(),
            displayKey: "productName"
        });
});

}

Re: How to add autocomplete in the site search?

Posted: Sun Jul 13, 2014 3:04 am
by gowthamgutha
How is fullproductname_t defined?

Re: How to add autocomplete in the site search?

Posted: Sun Jul 13, 2014 7:37 am
by RapidTransit
That was defined in my own SolrSearchServiceExtensionHandler via public ExtensionResultStatusType attachAdditionalBasicFields(Product product, SolrInputDocument document, SolrHelperService shs);

Re: How to add autocomplete in the site search?

Posted: Sun Jul 13, 2014 10:40 am
by gowthamgutha
Could you show me the snippet? Should I have to write an extension of that? If so, how and where should I make the class known to the Broadleaf framework?

Thanks.

Re: How to add autocomplete in the site search?

Posted: Mon Jul 14, 2014 1:40 pm
by gowthamgutha
I am unable to get the suggestion..

armageddon the hot sauce to end all

when I type amr?

Thanks.

Re: How to add autocomplete in the site search?

Posted: Tue Jul 15, 2014 10:01 am
by RapidTransit
Do you know what field you're searching on? I suggest reading some Solr documentation... Because what I gave you was my own implementation. To really use it you need to know more about Solr

Run Solr in a separate instance it will make understanding what's going on easier.

Re: How to add autocomplete in the site search?

Posted: Wed Jul 16, 2014 8:36 am
by gowthamgutha
I am searching on the field fullproductname_t and that it contains the name of the product (aka the default sku name)

Code: Select all

document.add("fullproductname_t",product.getName());


is what I've done.

Also, I need to know how to setup the Standalone solr server? I am getting the following error..

Unable to find /reindex in solr (404 Error - Not found)

I have run the Solr server before running Jetty and it is running in localhost:8983 but the url localhost:8983/reindex isn't found.

Thank you.

Re: How to add autocomplete in the site search?

Posted: Thu Jul 17, 2014 8:57 am
by RapidTransit
fullproductname_t was my own composed field

Look here : http://wiki.apache.org/solr/SolrJetty and https://cwiki.apache.org/confluence/dis ... r+on+Jetty
Example solr.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<solr>
    <cores adminPath="/admin/cores" defaultCoreName="primary">
        <core name="primary" instanceDir="primary" />
        <core name="reindex" instanceDir="reindex" />
    </cores>
</solr>

and is this in your solrconfig.xml

Code: Select all

    <requestHandler name="/admin/" class="solr.admin.AdminHandlers" />
    <requestDispatcher>
        <requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048000" />
        <httpCaching never304="true" />
    </requestDispatcher>

Re: How to add autocomplete in the site search?

Posted: Thu Jun 11, 2015 4:48 am
by letrangnhienanh
Hi RapidTransit,
Can you help me with fullproductname_t, where can I define it?

Thank you very much.