旧英语文本的短标题由缩写、数字、罗马数字和非英文字母组成。编程语言的内置排序功能不产生所需的结果。因此, 我们有一个内部开发的 Perl 脚本, oest_sort, 以排序的短标题。当为Apache Solr中的旧英语文本编制索引时, 为了按所需的顺序对结果进行排序, 我添加了一个序列字段, 根据 oest_sort 的结果为每个短标题分配一个数字。然而, 这个解决方案并不理想。最近, 我决定在 RuleBasedCollation 中使用自定义规则对文本进行排序

短标题排序规则

1. 将信存储在 A 之后。

2. 将租船放在一起。

不到位的租船标记为粗体。章程开始与 Ch 1 并且结束在魅力1之前。

在假如之前把我或假如。

排序 ChHead (章程) 在魅力之前 (不是章程)。

c. 排序港通作为 Ch 百升。

 ...
Ch 1 to Ch 1863
Ch IHen to Ch IWm
Ch I or IIWm
Ch IIWm
Ch [A-G][a-z]+
ChHl
Ch [I-Z][a-z]+
ChHead  
Charm 1
[Chr.Battle]
...

3. 使用数字排序对数字进行排序

CollGl 9 (Nap)
CollGl 11 (Voss)

4. 将罗马数字排序为数字

LawIAs
LawIIAs
LawIIIAtr
LawIVAs
LawVAs
LawVIAtr
LawVIIaAtr
LawVIIIAtr
LawIXAtr
LawXAtr

实现

1. 在solrconfig xml加载 Lucene 分析库以定义 solr。ICUCOllationField 和实施自定义排序顺序。

<config>
...
  <lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs/" regex="lucene-analyzers-icu-\d.*\.jar" />
  <lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lib/" regex="icu4j-.*\.jar" />
  <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-analy.*\.jar" />
...
</config>

2. 为规则1和2b 创建自定义排序顺序。

按照Solr Ref 指南 7.4中的自定义规则对文本进行排序, 创建自定义的排序规则并将其保存在 oeStRules. dat 中。

& A < æ << Æ& Ch < ChHead < Charm < Chr

3

<fieldType name="text_oe_st_sort" class="solr.ICUCollationField" strength="primary" custom="oeStRules.dat" alternate="shifted" numeric="true" caseFirst="lower"/>
<field name="st" type="text_general" indexed="true" stored="true"/>
<field name="st_sort" type="text_oe_st_sort" multiValued="false" indexed="true" stored="false"/>

4. 模式替换以为 st_sort 字段创建值, 实现规则2a、2c 和4。

...
# Roman numerals in Laws
$st =~ s/Law(X)([A-Z])/Law10$2/;
$st =~ s/Law(IX)([A-Z])/Law9$2/;
$st =~ s/Law(VIII)([A-Z])/Law8$2/;
$st =~ s/Law(VII)(aAtr.*)/Law7$2/;
$st =~ s/Law(VI)([A-Z])/Law6$2/;
$st =~ s/Law(V)([A-Z])/Law5$2/;
$st =~ s/Law(IV)([A-Z])/Law4$2/;
$st =~ s/Law(III)([A-Z])/Law3$2/;
$st =~ s/Law(II)([A-Z])/Law2$2/;
$st =~ s/Law(I)([A-Z])/Law1$2/;

# Treat ChHl as Ch Hl
$st =~ s/ChHl/Ch Hl/;

# Place IHen and IWm after Ch 1864 (so far the largest number)
$st =~ s/Ch IIHen/Ch 10012Hen/;
$st =~ s/Ch IHen/Ch 10011Hen/;
$st =~ s/Ch IIWm/Ch 10022Wm/;
$st =~ s/Ch IWm/Ch 10021Wm/;
$st =~ s/Ch I or IIWm/Ch 10013Hen/;

# Roman numerals
$st =~ s/ I / 1 /;
$st =~ s/ II / 2 /;
$st =~ s/ III / 3 /;
$st =~ s/ IV / 4 /;
$st =~ s/ V / 5 /;
$st =~ s/ VI / 6 /;
$st =~ s/ VII / 7 /;
$st =~ s/ VIII / 8 /;
$st =~ s/ IX / 9 /;
$st =~ s/ X / 10 /;
...

索引

1. 使用修改后的 solrconfig、托管架构和 oeStRules.dat 创建大量内核。

2. 启动 Solr 并装载批号核心。

3. 将 id、st 和所有其他字段的文本上载到批号核心;没有 st_sort 字段。

4. 从批号核心中提取 id 列表, 并将其保存到 st_oe. csv。

curl --output st_oe.csv 'http://localhost:8983/solr/lot/select?wt=csv&fl=id,st&q=*:*&rows=4000'

5. 使用 st_oe 作为源;将其反馈给 Perl 模式替换脚本, 以 JSON 格式输出结果, 将其保存到 st_sort. JSON。

[... {"id":"T09600", "st_sort":{"set":"Law10AtrProl"}},...]

6. 上传 st_sort, 为核心批次中的每个文档添加 st_sort 字段。

curl 'http://localhost:8983/solr/lot/update?commit=true' --data-binary @/path/to/st_sort.json -H 'Content-type:application/json'

7. 检查结果。

http://localhost:8983/solr/lot/select?wt=csv&fl=st&q=*:*&rows=4000&sort=st_sort%20asc

Az
ÆAbus (Mor)
...
CEdg
Ch 1 (Birch 3)
Ch 35 (Birch 227)
...
Ch 1863 (Finberg)
Ch IHen (Birch)
...
Ch IIHen (PRO1912 3)
Ch I or IIWm (Salter)
Ch IWm (BLAdd 29436)
...
Ch IIWm (PRO1906)
Ch Æþelweard (KellyApp 3.B)
Ch Brihtric (KellyApp 3.A)
Ch Edgar (Brooks)
ChHl (Kem 16)
Ch Lambourn (RobAppI 5)
Ch Odo (Loyd-Stenton)
...
Ch Wulfstan (Hearne)
ChHead 19 (Birch 97)
...
"ChHead 1438 (Birch 421, MS.C)"
Charm 1 (Storms)
...
Charm 22 (Storms)
Chr.Battle
"ChristA,B,C"
...
LawXAtrProl
LawAbt
...
LawIne
...

笔记

  • Solr。ICUCollationField 用于排序, 而不是用于搜索。因此, st 字段用于搜索和显示;而 st_sort 字段仅用于排序。st 字段需要进行索引和存储;虽然 st_sort 字段需要进行索引, 但不需要存储。
  • 首先, 我使用 < copyField 源 = “st” (st_sort) > 在托管架构中。当我创建一个 JSON 文件 [{“id”:, “…”, {“设置”: “st_sort”: “…”}}…]要设置需要模式替换的 st_sort 字段, 该值不替换旧值, 而是为字段添加了新值。将它变成多值字段。最后, 我为 st_sort 字段设置了多值 = “false”, 删除了 copyField, 并在初始索引处离开了 st_sort 字段。
  • 添加或更新, 只需对短标题进行替换, 并设置其 st_sort 字段。
  • Comments are closed.