我正在查询一个如下所示的facet字段:
<field name="brand" type="string" indexed="true" stored="false />
string
类型定义:
<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true"/>
我根据index
:f.brand.facet.sort=index
对
这给我一个这样的结果:
Aaaa (5)
Bbbb (14
Cccc (8)
abbb (29)
我想对不区分大小写的值进行排序,因此我尝试使用fieldType
创建新的LowerCaseFilterFactory
:
<fieldType name="text_facet" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
重建索引后,结果如下所示:
aaaa (5)
abbb (29)
bbbb (14)
cccc (8)
顺序正确,但现在的值也是LowerCase。
我想要这个结果:
Aaaa (5)
abbb (29)
Bbbb (14)
Cccc (8)
这里的大多数帖子都告诉我要创建一个copyField
,但我不明白在面向查询时我如何将这两个字段组合起来。
有没有办法对facet值进行排序不区分大小写,同时在查询时保留原始值?
答案 0 :(得分:1)
首先,没有直接的做法。我认为使用copyField
的建议是别的,但我可能会有所帮助。
我的想法如下:您创建类型为string
的品牌字段,而不是copyField
小写字段。
<field name="brand" type="string" indexed="true" stored="false"/>
<field name="brand_text" type="text_facet" indexed="true" stored="false"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true"/>
<fieldType name="text_facet" class="solr.TextField">
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<copyField source="brand" dest="brand_text" />
在查询期间,您只需查询两个字段以进行分面处理 - 在您的情况下,它将是这样的(我已经添加了一些文档):
brand:[Aaaa (1), Bbbb (1), Cccc (1), aBbb (1), abbb (1)]
brand_text:[aaaa (1), abbb (2), bbbb (1), cccc (1)]
只要按brand_text
排序,就可以获得原始方面的值,并以某种方式提供正确的响应。
但是,我想指出,类似的小写值可能会混合在一起。在我们的例子中,ABbb
和abbb
在小写模式下完全相同,所以问题是,你想在那里展示什么,所以我认为它应该得到妥善处理在业务逻辑方面。
通过扩展负责Solr faceting的org.apache.solr.handler.component.FacetComponent
,可以实现完全正确的解决方案。有一个代码正在进行排序:
boolean countSorted = dff.sort.equals(FacetParams.FACET_SORT_COUNT);
if (countSorted) {
counts = dff.countSorted;
if (counts == null || dff.needRefinements) {
counts = dff.getCountSorted();
}
} else if (dff.sort.equals(FacetParams.FACET_SORT_INDEX)) {
counts = dff.getLexSorted();
} else { // TODO: log error or throw exception?
counts = dff.getLexSorted();
}
和getLexSorted
正是对术语进行排序的原因:
Arrays.sort(arr, (o1, o2) -> o1.indexed.compareTo(o2.indexed));
您只需将toLowerCase()
应用于o1
和o2
。但是,这种方法将更加困难 - 您需要实现(扩展现有的FacetComponent,然后在solrconfig.xml中启用它,包括CI等)。