2012-11-13 11 views
9

Ciężko mi zrozumieć problem, który mam z bazą adresów SOLR.Problemy z sortowaniem alfabetycznym SOLR 4.0

Zbudowałem ten jeden z plików przykładowych. Zasadniczo uruchamiam przykładową konfigurację ze zmodyfikowanym schematem.

schema.xml:

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="_version_" type="long" indexed="true" stored="true" required="false" multiValued="false" /> 

<field name="givenname_s" type="text_de" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="middleinitial_s" type="text_de" indexed="false" stored="true" required="false" multiValued="false" /> 
<field name="surname_s" type="text_de" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="gender_s" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="pictureuri_s" type="string" indexed="false" stored="true" required="false" multiValued="false" /> 
<field name="function_s" type="text_de" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="organizationalunit_s" type="text_general" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="organizationalunitdescription_s" type="text_de" indexed="false" stored="true" required="false" multiValued="false" /> 
<field name="company_s" type="text_de" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="street_s" type="text_de" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="streetnumber_s" type="int" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="postcode_s" type="int" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="city_s" type="text_de" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="building_s" type="text_de" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="roomnumber_s" type="int" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="country_s" type="text_en" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="countrycode_s" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="emailaddress_s" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="phone1_s" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="phone2_s" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="mobile_s" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="fax_s" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 

ja wypełniania bazy danych poprzez naciśnięcie około 20,000 losowych zestawów danych testowych jak następujących do post.jar:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<add> 
    <doc> 
     <field name="id">1352498443_1</field> 
     <field name="givenname_s">Aynur</field> 
     <field name="middleinitial_s"/> 
     <field name="surname_s">Lehnen</field> 
     <field name="gender_s">F</field> 
     <field name="pictureuri_s">dummy_assets/female.jpg</field> 
     <field name="function_s">Zugschaffner/in</field> 
     <field name="organizationalunit_s">P 07</field> 
     <field name="organizationalunitdescription_s">Lorem Ipsum sadipscing voluptua ipsum invidunt dolor et dolore invidunt sed consetetur accusam dolore Lorem tempor.</field> 
     <field name="company_s">Lorem Lagna Epsum Emet</field> 
     <field name="street_s">Erlenweg</field> 
     <field name="streetnumber_s">82</field> 
     <field name="postcode_s">76297</field> 
     <field name="city_s">Lübeck</field> 
     <field name="building_s"/> 
     <field name="roomnumber_s">242</field> 
     <field name="country_s">GERMANY</field> 
     <field name="countrycode_s">DE</field> 
     <field name="emailaddress_s">[email protected]</field> 
     <field name="phone1_s">0392984823</field> 
     <field name="phone2_s">0124111417</field> 
     <field name="mobile_s">0325117132</field> 
     <field name="fax_s">0171459177</field> 
    </doc> 
</add> 

Jednak gdy Retreiving danych Wydaje mi się, że mam problemy z sortowaniem alfabetycznym. Rozważ następujące zapytanie:

{ 
    "responseHeader": { 
     "status": 0, 
      "QTime": 5, 
      "params": { 
      "sort": "surname_s asc", 
       "fl": "surname_s", 
       "indent": "true", 
       "wt": "json", 
       "q": "city_s:berlin" 
     } 
    }, 
     "response": { 
     "numFound": 1094, 
     "start": 0, 
     "docs": [{ 
      "surname_s": "Weil" 
     }, { 
      "surname_s": "Abel" 
     }, { 
      "surname_s": "Adam" 
     }, { 
      "surname_s": "Ade" 
     }, { 
      "surname_s": "Adrian" 
     }, { 
      "surname_s": "Aigner" 
     }, { 
      "surname_s": "Aigner" 
     }, { 
      "surname_s": "Alber" 
     }, { 
      "surname_s": "Alber" 
     }, { 
      "surname_s": "Albers" 
     }] 
    } 
} 

Dlaczego "Weil" na pozycji pierwszej, podczas gdy pozostałe dane wydają się być posortowane poprawnie?

Odpowiedz

14

Uważam, że niektóre z dodatkowych analizatorów, które są stosowane w polu typu text_de, są przyczyną tego zachowania podczas sortowania. Z mojego doświadczenia wynika, że ​​najlepsze wyniki przy sortowaniu łańcuchów to użycie fieldType alphaOlySort dostarczonego z przykładowym plikiem schema.xml pokazanym poniżej.

<fieldType name="alphaOnlySort" class="solr.TextField" sortMissingLast="true" omitNorms="true"> 
    <analyzer> 
    <!-- KeywordTokenizer does no actual tokenizing, so the entire 
     input string is preserved as a single token 
     --> 
    <tokenizer class="solr.KeywordTokenizerFactory"/> 
    <!-- The LowerCase TokenFilter does what you expect, which can be 
     when you want your sorting to be case insensitive 
     --> 
    <filter class="solr.LowerCaseFilterFactory" /> 
    <!-- The TrimFilter removes any leading or trailing whitespace --> 
    <filter class="solr.TrimFilterFactory" /> 
    <!-- The PatternReplaceFilter gives you the flexibility to use 
     Java Regular expression to replace any sequence of characters 
     matching a pattern with an arbitrary replacement string, 
     which may include back references to portions of the original 
     string matched by the pattern. 

     See the Java Regular Expression documentation for more 
     information on pattern and replacement string syntax. 

     http://java.sun.com/j2se/1.6.0/docs/api/java/util/regex/package-summary.html 
     --> 
    <filter class="solr.PatternReplaceFilterFactory" 
      pattern="([^a-z])" replacement="" replace="all" 
    /> 
    </analyzer> 
</fieldType> 

polecam stworzenie nowego pola, a następnie skopiowanie wartości z surname_s poprzez copyField, coś jak następuje:

<field name="surname_s_sort" type="alphaOnlySort" indexed="true" stored="false" required="false" multiValued="false" /> 

<copyField source="surname_s" dest="surname_s_sort"/> 

Uwaga: nie ma żadnej potrzeby, aby zapisać wartość w pole surname_s_sort, a więc atrybut stored="false", chyba że spodziewamy się wyświetlić to użytkownikom.

Następnie wystarczy zmienić zapytanie, aby posortować je na surname_s_sort.

+1

dla nikogo ten problem uwagę, że copyField się dzieje, gdy dokument jest indeksowany. –

+2

Twoje założenie jest absolutnie poprawne. "weil" jest hasłem dla GermanAnalyzer. –

+0

Perfect !! Dzięki Paige Cook. Zadziałało. – atpatil11

4

Sortowanie nie działa dobrze na polach wielowartościowych i tokenizowanych.

Documentation -
Sortowanie może odbywać się na „żywo” w dokumencie lub na dowolnym wielowartościowe = „false” indeksowanego = „true” polu pod warunkiem, że pole jest albo non-tokenized (czyli: nie ma Analyzer) lub używa analizatora, który generuje tylko jeden termin (tj. używa słowa kluczowego KeywordTokenizer). Jako typ pola użyj ciągu znaków i skopiuj pole tytułu do nowego pola.

<field name="surname_s_sort" type="string" indexed="true" stored="false"/> 

<copyField source="surname_s" dest="surname_s_sort" /> 

Jak @Paige odpowiedział można mieć tokenizera słów kluczowych, niższe filtry przypadków, które nie tokenize pole.

0

Miałem podobne problemy i próbowałem alphaOnlySort. Ta praca na część, ale zaczyna mieszać wyniki sortowania, gdy pole zawiera wartości takie jak -,/spacje itp.

więc wynik był coś

  1. /abc
  2. aa
  3. /abc2

Więc skończyło się używając typ pola małymi literami. To już było, więc pomyślałem, że jest to domyślny typ. Nie korzystałem budowę pola kopiowania, więc moja ostateczna config było:

<schema> 
    <fieldType name="lowercase" class="solr.TextField" positionIncrementGap="100"> 
     <analyzer> 
     <tokenizer class="solr.KeywordTokenizerFactory"/> 
     <filter class="solr.LowerCaseFilterFactory" /> 
     </analyzer> 
    </fieldType> 
    <fields> 
     <field name="job_name_sort" type="lowercase" indexed="true" stored="false" required="false"/> 
    </fields> 
    <copyField source="job_name" dest="job_name_sort"/> 
</schema> 
Powiązane problemy