Implement suggestions - BloomReach Experience - Open Source CMS

Implement suggestions

Solr can be configured to support suggestions while typing. Note that the current Solr implementations loads suggestions in memory, which can result in a large memory footprint if you have many unique terms (you could then also choose to load the suggestions only for the title field instead of for the default search field, normally containing all indexed text)

First of all, you need to configure the suggest in the solrconfig.xml:

Enable suggest in solrconfig.xml:

<!-- *** START SUGGEST ***-->
  <!-- ONLY INCLUDE THE SUGGEST COMPONENT WHEN ACTUALLY USED BECAUSE IT USES
       QUITE SOME MEMORY -->
  <searchComponent class="solr.SpellCheckComponent" name="suggest">
    <lst name="spellchecker">
      <str name="name">suggest</str>
      <!-- the indexed field to derive suggestions from -->
      <str name="field">text</str>
      <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
      <str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup
       </str>
      <!-- Alternatives to lookupImpl:
           org.apache.solr.spelling.suggest.fst.FSTLookup
               [finite state automaton]
           org.apache.solr.spelling.suggest.fst.WFSTLookupFactory
               [weighted finite state automaton]
           org.apache.solr.spelling.suggest.jaspell.JaspellLookup
               [default, jaspell-based]
           org.apache.solr.spelling.suggest.tst.TSTLookup
               [ternary trees]
      -->
      <!--float name="threshold">0.005</float-->
      <str name="buildOnCommit">true</str>
    </lst>

  </searchComponent>

  <requestHandler name="suggest"
                  class="org.apache.solr.handler.component.SearchHandler" >
    <lst name="defaults">
      <str name="spellcheck">true</str>
      <str name="spellcheck.dictionary">suggest</str>
      <str name="spellcheck.onlyMorePopular">true</str>
      <str name="spellcheck.count">100</str>
      <str name="spellcheck.collate">true</str>
    </lst>
    <arr name="components">
      <str>suggest</str>
    </arr>
  </requestHandler>
  <!-- *** END SUGGEST ***-->

Now, in your java code, you can use assuming we send a http request with the partial typed query as for exmaple ?suggestquery=hip

@Overridepublic void doBeforeServeResource(final HstRequest request,
                             final HstResponse response)
                                            throws HstComponentException {
    if (request.getParameter("suggestquery") == null) {
        // no query
        return;
    }

    HippoSolrClient solrClient =
      HstServices.getComponentManager().getComponent(
                    HippoSolrClient.class.getName(), "org.hippoecm.hst.solr");
    String suggest = request.getParameter("suggestquery");
    try {

        HippoQuery hippoQuery = solrClient.createQuery(suggest);

        // we want to get suggestions/autocompletion/didyoumean only!
        hippoQuery.getSolrQuery().setQueryType("suggest");
        HippoQueryResult result = hippoQuery.execute();

        // we do not need to bind the beans with their providers
        // for faceting, so no need for result.bindHits()

        // because suggestions reuse the spell check component, we can
        // use the spell check response
        request.setAttribute("collated",result.getQueryResponse()
                            .getSpellCheckResponse().getCollatedResult());
        request.setAttribute("suggestions",result.getQueryResponse()
                            .getSpellCheckResponse().getSuggestions());

    } catch (SolrServerException e) {
        throw new HstComponentException(e);
    }
}

and the JSP snippet. note that the collated var contains the auto suggested terms for every separate term in the suggestquery. For example if you have ?suggestquery=hipp cm , then the collated result might be for example hippo cms

Collated result: ${requestScope.collated}
<c:forEach var="suggestion" items="${requestScope.suggestions}">
<i>${suggestion.token}</i><br/>
  <c:forEach var="alternative" items="${suggestion.alternatives}"
             varStatus="counter">
    <c:if test="${counter.index < 7}">
          ${alternative}<br/>
    </c:if>
  </c:forEach>
 </c:forEach>
</div>
Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?