commit 16c6a5751ee446555c6ca415daaa0dfdb525bc79
Author: jpoubova <jpoubova@students.zcu.cz>
Date:   Sun May 3 01:02:27 2020 +0200

    Re #7917: Vyhledávání podle neúplných nebo podobných slov
    - lze vyhledávat s překlepy či neúplnými slovy
    - když nenalezne výsledky, hledá znovu s nejpodobnějším slovem
    - vrací se vždy to případně opravené hledané slovo (to bez překlepu)

diff --git a/be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/SolrService.java b/be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/SolrService.java
index 0a65a5c..d621ac0 100644
--- a/be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/SolrService.java
+++ b/be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/SolrService.java
@@ -9,6 +9,7 @@ import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CoreAdminRequest;
 import org.apache.solr.client.solrj.request.schema.SchemaRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.SpellCheckResponse;
 import org.apache.solr.client.solrj.response.schema.SchemaResponse;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
@@ -264,6 +265,8 @@ public class SolrService {
     public SearchResponse query(String query) throws IOException, SolrServerException  {
         LOG.trace("SolrService method query called");
         LOG.debug("Processing query - creating Solr query");
+
+        query = query.toLowerCase();
         SolrQuery solrQuery = new SolrQuery();
         solrQuery.set("q", FIELD_TEXT_REGION + ":" + query);
         solrQuery.setHighlight(true);
@@ -277,6 +280,25 @@ public class SolrService {
         SolrDocumentList docList = response.getResults();
         Map<String, Map<String, List<String>>> highlight = response.getHighlighting();
 
+        // if no documents found, try spell checking and call query again with first alternative
+        if (docList.size() < 1) {
+            LOG.info("No documents found, trying spell check...");
+            SpellCheckResponse spellCheck = response.getSpellCheckResponse();
+
+            if (spellCheck != null && spellCheck.getSuggestionMap().values().size() > 0) {
+                SpellCheckResponse.Suggestion first = spellCheck.getSuggestionMap().values().iterator().next();
+                List<String> alternatives = first.getAlternatives();
+
+                if (alternatives.size() > 0) {
+                    String alternative = alternatives.get(0);
+                    LOG.info("Spell check found alternative \"" + alternative + "\", calling query again with this alternative as parameter.");
+                    return query(alternative);
+                }
+            }
+
+            LOG.info("Spell check found no alternative.");
+        }
+
         SearchResponse searchResponse = new SearchResponse();
         searchResponse.setExpression(query);
 
diff --git a/solr/core-configs/documents/conf/documents-schema.xml b/solr/core-configs/documents/conf/documents-schema.xml
index 0d80a74..87e4b7f 100644
--- a/solr/core-configs/documents/conf/documents-schema.xml
+++ b/solr/core-configs/documents/conf/documents-schema.xml
@@ -453,6 +453,10 @@
   <field name="doc_filename" type="text_general" multiValued="false" stored="true"/>
   <field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
   <field name="img_filename" type="text_general" multiValued="false" stored="true"/>
+  
+	<field name="didyoumean" type="text_general" indexed="true" stored="true" multiValued="true"/>
+	<copyField source="text_region" dest="didyoumean"/>
+  
   <field name="text_region" type="text_general" multiValued="false" stored="true"/>
 <field name="text_region_coords" type="text_general" multiValued="false" indexed="false" stored="true"/>
   <field name="text_line_0" type="text_general" multiValued="false" stored="true"/>
diff --git a/solr/core-configs/documents/conf/solrconfig.xml b/solr/core-configs/documents/conf/solrconfig.xml
index b6cb65b..eb8bdc9 100644
--- a/solr/core-configs/documents/conf/solrconfig.xml
+++ b/solr/core-configs/documents/conf/solrconfig.xml
@@ -698,13 +698,30 @@
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <int name="rows">10</int>
+	  
+	  <str name="df">text_region</str>	  
+	  
+	  <str name="spellcheck.dictionary">default</str>
+      <str name="spellcheck">on</str>
+      <str name="spellcheck.extendedResults">true</str>
+      <str name="spellcheck.count">10</str>
+      <str name="spellcheck.alternativeTermCount">5</str>
+      <str name="spellcheck.maxResultsForSuggest">5</str>
+      <str name="spellcheck.collate">true</str>
+      <str name="spellcheck.collateExtendedResults">true</str>
+      <str name="spellcheck.maxCollationTries">10</str>
+      <str name="spellcheck.maxCollations">5</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
       <!-- Default search field
          <str name="df">text</str> 
         -->
       <!-- Change from JSON to XML format (the default prior to Solr 7.0)
          <str name="wt">xml</str> 
         -->
-    </lst>
+    <!-- </lst> -->
     <!-- In addition to defaults, "appends" params can be specified
          to identify values which should be appended to the list of
          multi-val params from the query (or the existing "defaults").
@@ -826,7 +843,7 @@
     -->
   <searchComponent name="spellcheck" class="solr.SpellCheckComponent">
 
-    <str name="queryAnalyzerFieldType">text_general</str>
+    <str name="queryAnalyzerFieldType">didyoumean</str>
 
     <!-- Multiple "Spell Checkers" can be declared and used by this
          component
@@ -835,7 +852,7 @@
     <!-- a spellchecker built from a field of the main index -->
     <lst name="spellchecker">
       <str name="name">default</str>
-      <str name="field">_text_</str>
+      <str name="field">text_region</str>
       <str name="classname">solr.DirectSolrSpellChecker</str>
       <!-- the spellcheck distance measure used, the default is the internal levenshtein -->
       <str name="distanceMeasure">internal</str>
