我正在尝试在SOLR中的字符串字段上进行字母数字排序。现在为此提出的一般解决方案是将填充数字设置为0并进行正常的字典排序。但这会将数字放在字母之前,而我的要求是字母应该出现在数字之前。
我是SOLR的新手。我可以在Java比较器中实现这种排序逻辑,但我发现我不能在SOLR中使用它。我在SOLR中探索了使用自定义函数(ValueSource)进行排序,但据我所知,它们一次对单个文档的字段值进行操作,并允许我们将这些值映射到另一个值(对于例如:像和函数一样)。从我到目前为止所见,没有类似比较器的相对评分功能(即一次比较2个文档)。我读过关于自定义相似性类的内容,但我认为它们并不适用于这种情况(可能有点矫枉过正?)
那我怎么能做到这一点?我能想到的唯一(非常丑陋和可怕)的解决方案是编写一个自定义SOLR函数,该函数用花括号(表中具有最大的ASCII值)围绕字符串中的任何数字。例如:a87
将转换为a{87}
。这促使他们持续。
答案 0 :(得分:0)
根据我的经验,我建议避免任何自定义相似性实现。
您可以创建一个analyzer链,将字母放在符合your case的数字之前。以下链a87
将转换为a000087
。如果这不符合您的确切要求,使用正则表达式可以根据需要修改字段。
<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);