How to build a dictionary for spellchecking in Solr? - solr

I'm trying to add spell checking to an existing Solr index.
I've added the following to the solrconfig.xml
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<str name="queryAnalyzerFiedlType">textSpell</str>
<lst name="spellchecker">
<str name="name">my_spell</str>
<str name="field">my_field</str>
<str name="buildOnOptimize">true</str>
<str nmae="spellcheckIndexDir">./spellchecker_my_spell</str>
</lst>
</searchComponent>
When I try to build the index with http://<myserver>:4103/my_index/select?&spellcheck=true&spellcheck.build=true&spellcheck.dictionary=cn_spell
I don't find any evidence that any dictionary is being built, either in the response, or in the file system.
What am I missing?

I forgot to add the query type to the query string. Adding &qt=dismax worked for me, since the spellcheck was the last-components of my dismax handler.

Related

Solr Suggester - dynamic or passed at runtime field

Is it possible to have dynamic field or pass field for suggestions at runtime (in query for example) for SuggestComponent?
Depending on user's language I would like to suggest him different things. I have dynamic field name_* that has concrete fields: name_pl, name_de and name_en (can be more, I want to have flexibility here) and I would like to search for suggestions depending on language: for pl I want to get suggestions in name_pl, for en in name_en and so on.
So far I have standard Suggester with field specified:
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">HighFrequencyDictionaryFactory</str>
<str name="">name_pl</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
</lst>
</searchComponent>
<requestHandler name="/suggest" class="solr.SearchHandler"
startup="lazy" >
<lst name="defaults">
<str name="suggest">true</str>
<str name="suggest.count">10</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
But actually I need either to use name_* or preferably at runtime to pass the field name for example: http://localhost:8983/solr/services/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=name&suggest.field=name_pl
How would you implement such mechanism?
It is not the answer you may expect but I started a comment and I ended up with this.
By using a dynamic field here you would have to rebuild the suggester at each query, I suggest ;) you require a specific suggestComponent' dictionary on query.
The value for field should remain static because it is parsed once to build a dictionary index from that field. Or you would have to delete/rebuild that index each time a suggest query requires a dictionary other than the one previously built.
Instead you should replicate the suggester definition for each language you may have so that Solr can build one dictionary index per field/language (just name the suggesters according to the target field language) :
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">suggest_nl</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">HighFrequencyDictionaryFactory</str>
<str name="field">name_pl</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
</lst>
<lst name="suggester">
<str name="name">suggest_en</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">HighFrequencyDictionaryFactory</str>
<str name="field">name_en</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
</lst>
<!-- etc. -->
</searchComponent>
Now you can query the target dictionary dynamically :
.../suggest?suggest=true&suggest.q=name&suggest.dictionary=suggest_nl
There is an easy way to do this, not sure if you are aware of it:
you create one dictionary per language: suggester_pl, suggester_en...each using the right field. They are all defined inside a single SuggestComponent
when calling, you select which one to hit with &suggest.dictionary=suggester_en
check the docs here

Solr query with filter query

I need to handle suggestion using solr query. Suggestion is working fine. But the problem is that suggestions are conditional i.e. suggestions are based on geo locations. I want the following equivalent query:
q=<SEARCH TERM>&fq=country:"<search country>"
I have tried some approaches but they are not working. What is the way to handle such scenarios?
Edit 1:
Suggester Config:
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">autofill</str>
<str name="contextField">allowed_location</str>
<str name="suggestAnalyzerFieldType">text_autofill</str>
<str name="buildOnStartup">false</str>
<str name="storeDir">path on file system</str>
</lst>
</searchComponent>
You will have to configure the suggester component in your solrconfig.xml qnd your suggestions queries need to be of the below form(shortened)
suggest.q=<search_term>&suggest.cfq=<search_country>
If you need the filtering query to work on country field, it must be configured as a contextField in your solrconfig.xml
For better understanding please refer to the reference guide link

Plugin for Solr Suggester Component

I created a plugin for Solr (version 6.3) that adds a permission layer to filter the retrieved documents using a database query (e.g: the user with ID 2 hasn't permissions to see the document with the ID 1); As the logic that defines if an user has permissions needs fields that aren't indexed in the Solr, i need to check in the database.
To achieve that i created a Query Parser (called DocumentsByUserParser that extends the class QParserPlugin) defined in the solrconfig.xml with the following:
<queryParser name="filterDocument" class="mypackage.solr.plugin.DocumentsByUserParser" />
To call this plugin, i only have to set the fq parameter with the {!filterDocument userId='<user_id>'} along with the other query parameters. Note that the code above works well with the Search Component with an edismax type.
My question is: can i create a new similar plugin, as described above, that works with the Suggest Component? Because when I index a document, the user may have (or not) permissions to see that document, so the suggester shouldn't show suggestions that the user hasn't permissions to see.
I defined my Suggest Component along with the Request Handler with the following:
<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
<str name="suggest">true</str>
<str name="suggest.count">10</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">AnalyzingInfixLookupFactory</str>
<str name="indexPath">suggester_infix_dir</str>
<str name="highlight">true</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">AUTO_COMPLETE_FIELD</str>
<str name="suggestAnalyzerFieldType">text_general</str>
<str name="buildOnStartup">false</str>
<str name="buildOnCommit">false</str>
</lst>
</searchComponent>
P.S - The context filter query described in https://lucene.apache.org/solr/guide/6_6/suggester.html only works with a single indexed field, so this will not work with my use case.

Solr auto suggest (suggester) returns no results

I am quite new to using solr5.1 - and I am now playing around to see if I can get the autosuggest to work. So, the background is that I have a core named docs and I post documents to this collection using something along the lines of:
/bin/post -c docs /path/to/my/docs/*.pdf
..and I have the documents indexed. Now, I tweak the solrconfig.xml, located within my core directory to include autosuggest. So, borrowing some code from here, I include the following:
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="storeDir">suggester_fuzzy_dir</str>
<!-- Substitute these for the two above for another "flavor"
<str name=”lookupImpl”>AnalyzingInfixLookupFactory</str>
<str name=”indexPath”>suggester_infix_dir</str>
-->
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">_text_</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
<str name="buildOnCommit">false</str>
</lst>
</searchComponent>
<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy" >
<lst name="defaults">
<str name="suggest">true</str>
<str name="suggest.count">10</str>
<str name="suggest.dictionary">mySuggester</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
Now, I do:
http://localhost:8983/solr/docs/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&wt=json&suggest.q=mode
and I always seem to get:
{"responseHeader":
{"status":0,"QTime":19},
"command":"build","suggest":
{"mySuggester":
{"mode":
{"numFound":0,"suggestions":[]}
}
}
}
I am not entirely sure what is it that I am doing wrong - I was wondering if I should be modifying the solrconfig.xml before adding any docs? or was it something wrong with the snippet of code inserted into it? Also, I am not sure if this line:
<str name="suggestAnalyzerFieldType">string</str>
is correct. I read that use of string should not be used - but again, I see the solr docs using it.
I have also tried code from here, but it seems to give me the same results - i.e no suggested words.
Any help on this would be great.
UPDATE: #01:
I have recently been reading that some features of solr need stored=true to work. I am now wondering if this applies to Suggester. So, do I need to turn the text field in solr.xml to stored=true?

Solr and spellcheck component : spellcheck.q doesn't take into consideration

I use spellcheck component and when I request solr I have results. But if I use spellcheck.q, i haven't result.
Someone has an idea ?
Thanks
<!-- The spell check component can return a list of alternative spelling
suggestions. -->
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<str name="queryAnalyzerFieldType">textSpell</str>
<lst name="spellchecker">
<str name="name">default</str>
<str name="field">spellCheck</str>
<str name="spellcheckIndexDir">./spellchecker</str>
<str name="buildOnCommit">true</str>
<str name="accuracy">0.4</str>
<float name="thresholdTokenFrequency">.0004</float>
</lst>
</searchComponent>
<!--<queryConverter name="queryConverter" class="solr.SpellingQueryConverter"/>-->
<!-- Handler par défaut -->
<requestHandler name="default" class="solr.SearchHandler" lazy="true" default="true">
<lst name="defaults">
<str name="spellcheck.onlyMorePopular">false</str>
<str name="spellcheck.extendedResults">false</str>
<str name="spellcheck.count">10</str>
<str name="hl.usePhraseHighLighter">true</str>
<str name="hl.highlightMultiTerm">true</str>
<str name="hl.mergeContiguous">true</str>
</lst>
<arr name="last-components">
<str>highlight</str>
<str>spellcheck</str>
</arr>
</requestHandler>
Have you added your spellcheck component to the corresponding request handler (in solr config), set spellcheck parameter to true (or on) and configured the correct dictionary to use (if its name different than "default")?
If you don't use the spellcheck.q parameter, then the default is to use the q parameter (from http://wiki.apache.org/solr/SpellCheckComponent#q_OR_spellcheck.q). From that wiki:
Essentially, if you have a spelling "ready" version in your application, then it is probably better to send spellcheck.q, otherwise, if you just want Solr to do the job, use the q parameter
The reason that it works if you change the definition of the field type is probably due to the new field type being "spelling ready". It would help if you posted the query you are using and the relevant lines in the schema.xml.

Resources