通过本文,你将学习到:
- solr中字段的概念
- 字段的必要属性
- 多值的字段
- 动态字段
- 复制字段
- 唯一键字段
solr 中字段的概念
说起solr中的字段(field),我们要先搞清楚文档(document)是什么。事实上,Solr的基本信息单位就是document,document是用来描述某种事物的。如果你有面向对象的编程经验,“某种事物”是很好理解的,假设我们要开发一个手表搜索应用,我们认为下面表格中的字段,对于描述手表“这种事物”来说是必不可少的:
字段 | 值 |
id | 1 |
watchName | 日志型 II |
model | 116300 |
description | 该腕表于2009年面世,在其增大的表壳内,蕴含了劳力士最新的技术 |
正如上面的表格所示,我们选取了手表来代表solr中的document。在现实生活中,还有很多这样的例子,比如说,如果你使用书籍代表document,那么它可能有:作者、出版时间、页数、价格等等字段。
字段的必要属性
对于每个字段而言,它必要包含一个唯一的,在构建查询时被使用的名字,比如说:watchName:日志型II。这个查询意味着用户要查询名称(watchName)为:日志II的手表。对于该字段的定义,请参考下面的代码片段:
<field name="watchName" type="string" indexed="true" stored="true" />
通俗的说,上面的这种定义意味着名为“watchName”的字段将会存储一个类型为string的值,并且该字段将会被索引和被存储。每个字段都必须使用type来定义其类型,同时每个字段也要定义它是否被索引和(或)被存储。被索引的字段能够被搜索和排序;被存储的字段能够在搜索结果中显示出来。
多值的字段
上面我们用来描述手表的字段,是很简单的,现在我们考虑这样一种场景,“日志型II”也被称为“DateJust II”,如果用户搜索“watchName:DateJust”,很明显他们是看不到希望的结果的。solr提供了这样一种机制:多值字段。它可以使用多个值填充到同一个字段。在schema.xml中,你可以通过在字段上设置multiValued="true"来表示该字段是一个多指的字段:
<field name="watchName" type="string" indexed="true" stored="true" multiValued="true"/> </span>
动态字段
在我们的手表示例中,watchName和model字段都是string类型的,这两个字段除了name属性不一样之外,其他属性(indexed,stored)都是相同的。想象一下,除了这两个字段之外,如果我们还有几十个string的字段,我们是不是应该为它们中的每一个的在schema.xml中定义呢?如果还有其他类型相同,其他属性也形同,仅仅是名称不同的字段呢?请看如下定义:
<field name="field1" type="string" indexed="true" stored="true" /> <field name="field2" type="string" indexed="true" stored="true" /> <field name="field3" type="string" indexed="true" stored="true" /> ... <field name="field4" type="string" indexed="true" stored="true" /> <field name="field5" type="string" indexed="true" stored="true" /> <field name="fieldn" type="string" indexed="true" stored="true" />
事实上,solr提供了一种叫做动态字段的机制:动态字段允许在你的document中任何字段应用相同的定义,只要字段的名字匹配前缀或者后缀表达式(就像s_*或者*_s)中的一个。动态字段使用一个特殊的命名机制以应用相同的字段定义针对任何符合这种通配符式样模式的字段。使用动态字段,我们可以通过很简单的代码来达到同样的效果:
<dynamicField name="*_s" type="string" indexed="true" stored="true" />
你也可以为多值的字段使用动态字段,即在动态字段定义中加上multiValued="true"属性。
复制字段
在大多数的搜索应用中,用户会看到一个可以输入查询的简单的搜索框。这种途径的目的是帮助你的用户快速地找到document,而不必填充一个复杂的表单。想象下,用户在watchName字段上搜索“116300“(手表的型号),这种情况下用户是不能找的他们心仪的结果的,因为”116300“被保存在名为”model“的字段上而不是”watchName“字段上。其实复制字段与传统数据库的的某些机制有些类似,比如我们可以用sql模拟下当前的情景:
where watchName like ‘%116300%’ or model like '116300'
对于solr而言,它提供<copyField>指令使得从你的document众多其他字段来创建一个单一的包罗万象的字段,该字段包含若干个由我们指定的字段的文本。
首先,你需要定义一个目标字段,其他字段的值将会被复制到该字段,让我们称之为“catch_all”:
<field name="catch_all" type="text_en" indexed="true" stored="false" multiValued="true"/>
请注意,"catch-all"字段不应该被存储,因为它是由其他字段填充的;此外,如果有一个源字段是多值的,那么目标字段应该也是多值的。
然后,我们需要告诉Solr从哪些字段中复制(使用<copyField>机制)。下面的清单显示了,我们如何使用<copyField>机制,从watchName,model,和 description字段中复制值到我们的“catch_all”字段。
<schema> <fields> ... </fields> <copyField source="watchName" dest="catch_all" /> <copyField source="model" dest="catch_all" /> <copyField source="description" dest="catch_all" /> <types> ... </types> </schema>
唯一键字段
唯一键比较容易理解,它使用一个独一无二的ID值使得你的文档唯一的被识别在索引中。在schema.xml中,它的定义如下:
<uniqueKey>id</uniqueKey>