2017-03-12 74 views
0

我嘗試在SOLR中的字符串字段上進行字母數字排序。現在提出的一般解決方案是使填充字符的數字爲0,並進行正常的字典排序。但是這會把數字放在字母之前,而我的要求是字母應該在數字之前。SOLR - 首字母爲字母數字排序

我是SOLR的新手。我可以在Java比較器中實現這種排序邏輯,但是我發現我不能在SOLR中使用它。我研究了在SOLR中使用自定義函數(ValueSource)進行排序,但據我瞭解,它們一次對單個文檔的字段值進行操作,並允許我們將這些值映射到另一個值(例如:總和功能)。從目前爲止我所看到的沒有類比較器的相對評分功能(即一次比較兩個文檔)。我讀了關於自定義相似類,但我不認爲它們適用於這種情況(並可能是矯枉過正?)

那麼我怎麼能做到這一點?我能想到的唯一(非常難看且可怕的)解決方案是編寫一個自定義的SOLR函數,該函數圍繞花括號(表中最大的ASCII值)字符串中的任何數字。例如:a87將轉換爲a{87}。這推動他們持續下去。

回答

0

根據我的經驗,我建議避免任何自定義相似性實現。

您可以創建一個analyzer連鎖店,在符合您的your case的數字前放置字母。隨着以下鏈條a87將轉換爲。如果這不符合你的要求,使用正則表達式,你可以根據你的需要來改變字段。

<fieldType name="alphaNumericSort" class="solr.TextField" sortMissingLast="false" 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" /> 
    <!-- Left-pad numbers with zeroes --> 
    <filter class="solr.PatternReplaceFilterFactory" 
      pattern="(\d+)" replacement="00000$1" replace="all" 
    /> 
    <!-- Left-trim zeroes to produce 6 digit numbers --> 
    <filter class="solr.PatternReplaceFilterFactory" 
      pattern="0*([0-9]{6,})" replacement="$1" replace="all" 
    /> 
    <!-- Remove all but alphanumeric characters --> 
    <filter class="solr.PatternReplaceFilterFactory" 
      pattern="([^a-z0-9])" replacement="" replace="all" 
    /> 
    </analyzer> 
</fieldType> 

如果你沒有關於建立新的領域的特殊要求,我會建議建立在你的managed-schema一個新的複製有原始字段。

<field name="myNewField" type="alphaNumericSort" indexed="true" stored="true" /> 
<copyField source="sourceField" dest="myNewField" /> 

如果這仍然不適合你的問題,另一種解決方案是將原始場成一個或多個新字段(總是使用之前提到的分析器鏈)它們中的每含有可替代地,字母和數字部分。

通過這種方式,您可以按照您所需的順序將輸出傳遞給標準的sort查詢子句。例如:

sort=fieldAlpha1 asc, fieldNumeric1 desc, fieldAlpha2 asc 

或者在Solrj

solrQuery.addSortField("fieldAlpha1", ORDER.asc); 
solrQuery.addSortField("fieldNumeric1", ORDER.desc); 
solrQuery.addSortField("fieldAlpha2", ORDER.asc); 
+0

感謝您的答覆! 「你可以創建一個分析儀鏈,在數字之前放置字母」 - 我無法弄清楚如何做到這一點。正如我所說的,單獨留下填充對我來說是不夠的(因爲它會把數字放在第一位)。你提供的鏈接也是一樣的。 「使用正則表達式,你可以隨心所欲地破壞領域」 - 這是否意味着我可以使用我的花托架解決方案? 關於創造新領域,我認爲這不可行。我有2500個這樣的字段來對字母數字進行排序,並且創建與每個對應的新字段將導致太多的字段。 – Sri

+0

..有限。這就是爲什麼我想要製作一個自定義函數,它可以實時返回強制值,而不是將其存儲爲字段。另外,關於你的最後一點(多重排序) - 如果字符串中有很多交替的alpha和num部分,這不會失敗嗎?像a100b200c300例如? – Sri

+0

自定義函數也對相關性有影響,可能這不是你想要的。你真的有2500個字母數字字段來排序嗎?您能否發佈一份真實的數據樣本? – freedev