solr中的非英文排序问题解决

我们知道,solr支持utf-8字符编码,因此可以支持任何的国家语言。但是如果你需要对特殊国家的语言(非英语)进行排序,你会发现使用标准的solr string 类型,排序并不能够很好的实现。

 

为了说明解决方法,我们假定需要排序的文本中有Polish字符,为了说明好的和坏得两中排序方式,我建立下面索引结构(将下面的内容加入到你的schema文件中)。

<field name="id" type="string" indexed="true" stored="true"required="true" />
<field name="name" type="text" indexed="true" stored="true" />

<field name="name_sort_bad" type="string" indexed="true" stored="true"/>
<field name="name_sort_good" type="text_sort" indexed="true"stored="true" />

我也定义一些拷贝字段来自动填充 name_sort_bad 和name_sort_good
两个字段。

<copyField source="name" dest="name_sort_bad" />
<copyField source="name" dest="name_sort_good" />

最后在schema.xml文件中加入一个新的类型,这样text_sort类型的定义看上去像这样:

<fieldType name="text_sort" class="solr.TextField">
<analyzer>
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.CollationKeyFilterFactory" language="pl"
country="PL" strength="primary" />
</analyzer>
</fieldType>

测试数据如下:

<add>
<doc>
<field name="id">1</field>
<field name="name">Łaka</field>
</doc>
<doc>
<field name="id">2</field>
<field name="name">Lalka</field>
</doc>
<doc>
<field name="id">3</field>
<field name="name">Zab</field>
</doc>
</add>

首先,我们看一下不正确的排序方式是怎么样的,为了实现这个目的,我们向solr发送下面的查询请求:

http://localhost:8983/solr/select?q=*:*&sort=name_sort_bad+asc&indent=true

上面的查询得到的排序结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params">
<str name="q">*:*</str>
<str name="sort">name_sort_bad asc</str>
</lst>
</lst>
<result name="response" numFound="3" start="0">
<doc>
<str name="id">2</str>
<str name="name">Lalka</str>
<str name="name_sort_bad">Lalka</str>
<str name="name_sort_good">Lalka</str>
</doc>
<doc>
<str name="id">3</str>
<str name="name">Zab</str>
<str name="name_sort_bad">Zab</str>
<str name="name_sort_good">Zab</str>
</doc>
<doc>
<str name="id">1</str>
<str name="name">Łaka</str>
<str name="name_sort_bad">Łaka</str>
<str name="name_sort_good">Łaka</str>
</doc>
</result>
</response>

Now let's send the query that should return the documents sorted in the correct order. The
query looks like this:

现在我们向solr发出一个请求,这个请求将返回按照正确顺序排序的文档,请求如下:

http://localhost:8983/solr/select?q=*:*&sort=name_sort_good+asc&indent=true

sorl的返回结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">6</int>
<lst name="params">

<str name="q">*:*</str>
<str name="sort">name_sort_good asc</str>
</lst>
</lst>
<result name="response" numFound="3" start="0">
<doc>
<str name="id">2</str>
<str name="name">Lalka</str>
<str name="name_sort_bad">Lalka</str>
<str name="name_sort_good">Lalka</str>
</doc>
<doc>
<str name="id">1</str>
<str name="name">Łaka</str>
<str name="name_sort_bad">Łaka</str>
<str name="name_sort_good">Łaka</str>
</doc>
<doc>
<str name="id">3</str>
<str name="name">Zab</str>
<str name="name_sort_bad">Zab</str>
<str name="name_sort_good">Zab</str>
</doc>
</result>
</response>

这次的排序是正确的,下面我们看一下排序是如何实现的。

索引中的每一个文档都包含4个字段,id字段是文档的唯一标识,name字段包括是文档的名字,最后的两个字段是用来排序的。

name_sort_bad字段不是新的,它是基于string类型的字段,通常用来做排序。name_sort_good字段是新的---text_sort字段类型,这个类型是基于solr.TextField和solr.KeywordTokenizerFactory,他的意思是文本不被分词。我们利用这个技巧是因为我们希望基于这个字段对文档进行排序而不是希望他被分词。

另一方面,我们需要用新的fileter实现文档的正确排序。能够让solr实现正确排序的filter是solr.CollationKeyFilterFactory,对这个filter我们使用了3个属性,

1.language:告诉solr字段的语言

2.country:告诉solr国家

3.strength:告诉solr使用的collection长度。

1,2两个个属性是solr构造locale必须的,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值