[solr] schema.xml

 

solr数据的输入和查询输出都是以document形式在服务器和客户端之间传输的,而schema.xml则定义了这些数据的详细格式,如字段名、数据类型、是否索引该字段,是否存储该字段等,还有一些参数可以定制和优化字段的解析和查询策略。下面我们就来看一下schema的一些介绍。

 

基本结构:

 <!-- schema.xml -->
<schema> <fields> <field /> <dynamicField /> </fields> <uniqueKey></uniqueKey> <copyField /> <types> <fieldType /> <fieldType> <analyzer /> <analyzer> <tokenizer /> <filter /> <filter /> </analyzer> </fieldType> </types> <similarity> <str></str> <float></float> <!-- .... --> </similarity> <schema>

 

1. types

types的子节点FieldType定义schema中field的字段类型

    

    <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/> 

  • name:类型名称
  • class:指向org.apache.solr.analysis包里面对应的class名称,用来定义这个类型的行为。
  • precisionStep是在做range search的起作用的,默认值是4;数值类型(int float double)在Lucene里都是以string形式存储的,当然这个string是经过编码的,经过编码后的string保证是顺序的,也就是说num1>num2,那么strNum1>strNum2。precisionStep用来分解编码后的string,例如有一个precisionStep,默认是4,也就是隔4位索引一个前缀,比如0100,0011,0001,1010会被分成下列的二进制位“0100,0011,0001,1010“,”0100,0011,0001“,0100,0011“,”0100“。这个值越大,那么索引就越小,那么范围查询的性能(尤其是细粒度的范围查询)也越差;这个值越小,索引就越大,那么性能越差。就讲这么多了,如果希望进一步了解,参见:http://ecm-kit.15604.n6.nabble.com/solr-precisionStep-positionIncrementGap-td5000919.html#a5000920
  • positionIncrementGap:用在多值字段的匹配规则上。例如有一个多值字段有2个值A和B。如果positionIncrementGap=0;那么A和B对应的位置0,1,那么查询“A B”你是可以命中的。假如你不希望命中,你可以将positionIncrementGap设置为100,这时,A和B对应的位置0,101,那么此时查询“A B”将无结果。

 

    必要的时候fieldType还需要自己定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤,如下

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">

      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
        <!-- in this example, we will only use synonyms at query time
        <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
        
-->
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>

</fieldType> 

 关于analyzer这个链接里应该已经讲的比较清楚了http://www.solrcn.com/?p=131,filter是用来过滤分析器分析完之后的tokens,如StopFilterFactory用来排除一些停用词。

 

2. fields

fields节点是用来定义具体的document字段信息的,包括这个字段的类型、是否索引等,具体的参数如下:

  • name:字段名字
  • type:该字段的类型,fieldType里定义的各种type之一
  • indexed:该字段是否建立索引
  • stored:该字段是否被存储
  • multiValued:在同一个document中该字段是否有多个值
  • default:默认值
  • compressed:true|false,是否gzip压缩存储,只有当前字段可压缩才有用,在solr标准的fieldType中只有TextField和StrField能压缩
  • compressThreshold:
  • 还有一些字段请参考http://wiki.apache.org/solr/SchemaXml#Common_field_options

 

multiValue:举个例子就比较清楚了

<doc>
<id></id><field name=keywords>solr<field/> 
<field name=keywords>lucene<field/> 
<field name=keywords>seach<field/> 

</doc> 

也就是说一个doc里可能出现多个同样的field字段。 

 

注:fields的定义应对可能存在多值的字段尽量设置multiValued属性为true,避免建索引时抛出错误;如果不需要存储相应字段值,尽量将stored属性设为false,因为如果单个doc的数据量增加,在查询结果里会返回很多并不需要的字段,没有意义却反而影响到查询效率。  

 

3. copyField 

一个doc里可以有多个copyField的定义节点,即将多个字段的值依次拷贝一份到指定字段,

  1. <copyField source="name" dest="all"/>  
  2. <copyField source="summary" dest="all"/>  

 上面的两个定义就是把name和summary的值拷贝到字段all里。

建议建立一个拷贝字段,将所有的 全文本 字段复制到一个字段中,以便进行统一的检索。

4. dynamicField 

动态字段,和Field标签一样,只是用name来匹配字段,如name="*_i",可以匹配到name_i,abc_i。

5. similarity

 用于solr评分修改的,评分是在排序时使用的字段属性,详情可参考http://www.solr.cc/blog/?p=66这里。

 

--------------- 下面转自http://yinwufeng.iteye.com/blog/964040 -------------- 

 schema.xml文档注释中的信息:

1、为了改进性能,可以采取以下几种措施:

  • 将所有只用于搜索的,而不需要作为结果的field(特别是一些比较大的field)的stored设置为false
  • 将不需要被用于搜索的,而只是作为结果返回的field的indexed设置为false
  • 删除所有不必要的copyField声明
  • 为了索引字段的最小化和搜索的效率,将所有的 text fields的index都设置成field,然后使用copyField将他们都复制到一个总的 text field上,然后对他进行搜索。
  • 为了最大化搜索效率,使用java编写的客户端与solr交互(使用流通信)
  • 在服务器端运行JVM(省去网络通信),使用尽可能高的Log输出等级,减少日志量。

2、< schema name =" example " version =" 1.2 " >

  • name:标识这个schema的名字
  • version:现在版本是1.2

3、filedType

< fieldType name =" string " class =" solr.StrField " sortMissingLast =" true " omitNorms ="true " />

  • name:标识而已。
  • class和其他属性决定了这个fieldType的实际行为。(class以solr开始的,都是在org.appache.solr.analysis包下)

可选的属性:

  • sortMissingLast和sortMissingFirst两个属性是用在可以内在使用String排序的类型上(包括:string,boolean,sint,slong,sfloat,sdouble,pdate)。
  • sortMissingLast="true",没有该field的数据排在有该field的数据之后,而不管请求时的排序规则。
  • sortMissingFirst="true",跟上面倒过来呗。
  • 2个值默认是设置成false

StrField类型不被分析,而是被逐字地索引/存储。

StrField和TextField都有一个可选的属性“compressThreshold”,保证压缩到不小于一个大小(单位:char)

< fieldType name =" text " class =" solr.TextField " positionIncrementGap =" 100 " >

solr.TextField 允许用户通过分析器来定制索引和查询,分析器包括 一个分词器(tokenizer)和多个过滤器(filter)

  • positionIncrementGap:可选属性,定义在同一个文档中此类型数据的空白间隔,避免短语匹配错误。

< tokenizer class =" solr.WhitespaceTokenizerFactory " />

空格分词,精确匹配。

< filter class =" solr.WordDelimiterFilterFactory " generateWordParts =" 1 " generateNumberParts =" 1 " catenateWords =" 1 " catenateNumbers =" 1 " catenateAll =" 0 " splitOnCaseChange ="1 " />

在分词和匹配时,考虑 "-"连字符,字母数字的界限,非字母数字字符,这样 "wifi"或"wi fi"都能匹配"Wi-Fi"。

< filter class =" solr.SynonymFilterFactory " synonyms =" synonyms.txt " ignoreCase =" true" expand =" true " />

同义词 

< filter class =" solr.StopFilterFactory " ignoreCase =" true " words =" stopwords.txt " enablePositionIncrements =" true " />

在禁用字(stopword)删除后,在短语间增加间隔

stopword:即在建立索引过程中(建立索引和搜索)被忽略的词,比如is this等常用词。在conf/stopwords.txt维护。

4、fields

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

  • name:标识而已。
  • type:先前定义的类型。
  • indexed:是否被用来建立索引(关系到搜索和排序)
  • stored:是否储存
  • compressed:[false],是否使用gzip压缩(只有TextField和StrField可以压缩)
  • mutiValued:是否包含多个值
  • omitNorms:是否忽略掉Norm,可以节省内存空间,只有全文本field和need an index-time boost的field需要norm。(具体没看懂,注释里有矛盾)
  • termVectors:[false],当设置true,会存储 term vector。当使用MoreLikeThis,用来作为相似词的field应该存储起来。
  • termPositions:存储 term vector中的地址信息,会消耗存储开销。
  • termOffsets:存储 term vector 的偏移量,会消耗存储开销。
  • default:如果没有属性需要修改,就可以用这个标识下。

< field name =" text " type =" text " indexed =" true " stored =" false " multiValued =" true " />

包罗万象(有点夸张)的field,包含所有可搜索的text fields,通过copyField实现。

< copyField source =" cat " dest =" text " />

  < copyField source =" name " dest =" text " />
  < copyField source =" manu " dest =" text " />
  < copyField source =" features " dest =" text " />
  < copyField source =" includes " dest =" text " />

在添加索引时,将所有被拷贝field(如cat)中的数据拷贝到text field中

作用:

  • 将多个field的数据放在一起同时搜索,提供速度
  • 将一个field的数据拷贝到另一个,可以用2种不同的方式来建立索引。

< dynamicField name =" *_i " type =" int " indexed =" true " stored =" true " />

如果一个field的名字没有匹配到,那么就会用动态field试图匹配定义的各种模式。

  • "*"只能出现在模式的最前和最后
  • 较长的模式会被先去做匹配
  • 如果2个模式同时匹配上,最先定义的优先

< dynamicField name =" * " type =" ignored " multiValued=" true " />

如果通过上面的匹配都没找到,可以定义这个,然后定义个type,当String处理。(一般不会发生)

但若不定义,找不到匹配会报错。

5、其他一些标签

< uniqueKey > id </ uniqueKey >

文档的唯一标识, 必须填写这个field(除非该field被标记required="false"),否则solr建立索引报错。

< defaultSearchField > text </ defaultSearchField >

如果搜索参数中没有指定具体的field,那么这是默认的域。

< solrQueryParser defaultOperator =" OR " />

配置搜索参数短语间的逻辑,可以是"AND|OR"。

 

拷贝和引用:

Solr Schema.xml和solrconfig.xml分析

http://wiki.apache.org/solr/SchemaXml

http://wiki.apache.org/solr/SchemaXml

轻轻松松学Solr(4)--Solr Schema (下)

solr中precisionStep和positionIncrementGap的含义和作用

Lucene 4 和 Solr 4 学习笔记(3)

 

存个链接:

http://www.pathbreak.com/blog/solr-text-field-types-analyzers-tokenizers-filters-explained

http://rdc.taobao.com/team/jm/archives/1753

 

posted on 2013-04-20 20:42  我不是地球人  阅读(861)  评论(0)    收藏  举报

导航