2017-03-12 42 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