1
votes

I am trying to search for a term that has spaces and a wildcard at the end of it; i.e. name:John S* Solr is failing to return any result although I have the below entries indexed and are returned when querying *:* from Solr web interface;

  • John Dow
  • Johny English
  • John Smith

I am using Sol7.4 with DIH that index my DB, and I am creating a contact search (by name and phone) feature to my web app.

I have followed this thread Solr wildcard query with whitespace however it did not solve the problem;

  1. I have tried changing my field type (for field name) to text_en, text_ws and currently text_general, plus, tried to escape spaces with a backslash "\ " and it did not work.
  2. Tried Solr "complex phrase query parser" which partially solved the issue, as it will extremely increase the query time, in addition, Solarium is throwing an exception if the term contains spaces at the end i.e. "jhon\ *" and if I try to run the same query from Solr web interface I got no result http://localhost:8983/solr/collection/select?q{!complexphrase inOrder=true}displayName:John\ *
  3. Also, tried Prefix Query Parser with no luck

Note: that I have reloaded solr, cleared and re-index my data after each try.

Expected result:

  • when searching for "John" I should get all the 3 entries:

    • John Dow
    • Johny English
    • John Smith
  • when searching for "John\ " that will be parsed to "John "; I should get:

    • John Dow
    • John Smith
  • and when searching for "John\ S*", I should be getting:

    • John Smith

Update #1

search.php

...
    $term = str_replace(' ', '\ ', $request_params['term']);
    $query->setQuery('phone:"%1%" OR name:"%1%" OR contact:%2%*', [$request_params['term'], $term]);
    // $query->setQuery('phone:"%1%" OR name:"%1%" OR contact:"%2%*"', [$request_params['term'], $term]);
...

managed-schema

...
  <fieldType name="lowercase" class="solr.TextField" positionIncrementGap="100">
    <analyzer>
      <tokenizer class="solr.KeywordTokenizerFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>
...
  <field name="name" type="text_general" multiValued="false" indexed="true" stored="true"/>
  <field name="contact" type="lowercase" indexed="true" stored="true"/>
  <field name="phone" type="string" docValues="false" multiValued="false" indexed="true" required="true" stored="true"/>
  <copyField source="displayName" dest="card"/>
  <!-- <copyField source="phone" dest="card"/> -->
...
1

1 Answers

2
votes

Use a second field for wildcard matches that has a KeywordTokenizer with a LowercaseFilterFactory attached. Use a copyField instruction to copy the content from the main field into the second, wildcard based field.

That way you can perform regular searches against the regular field, while performing wildcard searches against the field that supports wildcards properly.

Your second example above (John\ *) in effect will probably only match anything that has the token John present (and you're missing a = between the argument name q and the argument itself).