schema.xml位于solr/conf/目录下,类似于数据表配置文件,定义了加入索引的数据的数据类型,主要包括type、fields和其他的一些缺省设置

  1、schema的基本配置

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="user" version="1.6">
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="name" type="text_general" indexed="true" stored="true"/>
<uniqueKey>id</uniqueKey> <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymGraphFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
<filter class="solr.FlattenGraphFilterFactory"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
</schema>

  2、常规Field设置

    在fields结点内定义具体的字段(类似数据库中的字段),就是filed,filed定义包括name,type(为之前定义过的各种FieldType),indexed(是否被索引),stored(是否被储存),multiValued(是否有多个值)等等

<fields>
  <field name="id" type="integer" indexed="true" stored="true" required="true" />
  <field name="name" type="text" indexed="true" stored="true" />
  <field name="summary" type="text_general" indexed="true" stored="true" />
  <field name="date" type="date" indexed="false" stored="true" />
  <field name="content" type="text_general" indexed="true" stored="false" />
  <field name="keywords" type="keyword_text" indexed="true" stored="false" multiValued="true" />
  <field name="title" type="keyword_text" indexed="true" stored="false" multiValued="true"/>
</fields>

    field属性说明:

    name:属性的名称,这里有个特殊的属性“_version_”是必须添加的。

    type:字段的数据结构类型,所用到的类型需要在fieldType中设置。

    default:默认值。

    indexed:是否创建索引

    stored:是否存储原始数据(如果不需要存储相应字段值,尽量设为false)

    docValues:表示此域是否需要添加一个 docValues 域,这对 facet 查询, group 分组,排序, function 查询有好处,尽管这个属性不是必须的,但他能加快索引数据加载,对 NRT 近实时搜索比较友好,

        且更节省内存,但它也有一些限制,比如当前docValues 域只支持 strField,UUIDField,Trie*Field 等域,且要求域的域值是单值不能是多值域

    solrMissingFirst/solrMissingLast:查询结果排序的过程中,如果发现这个字段的值不存在,则排在前面/后面,忽略排序的条件

    multValued:是否有多个值,比如说一个用户的所有好友id。(对可能存在多值的字段尽量设置为true,避免建索引时抛出错误)

    omitNorms:此属性若设置为 true ,即表示将忽略域值的长度标准化,忽略在索引过程中对当前域的权重设置,且会节省内存。只有全文本域或者你需要在索引创建过程中设置域的权重时才需要把这个值设为 false,

        对于基本数据类型且不分词的域如intFeild,longField,StrField 等默认此属性值就是 true, 否则默认就是 false.

    required:添加文档时,该字段必须存在,类似mysql的not null

    termVectors: 设置为 true 即表示需要为该 field 存储项向量信息,当你需要MoreLikeThis 功能时,则需要将此属性值设为 true ,这样会带来一些性能提升。

    termPositions:是否存储 Term 的起始位置信息,这会增大索引的体积,但高亮功能需要依赖此项设置,否则无法高亮

    termOffsets:表示是否存储索引的位置偏移量,高亮功能需要此项配置,当你使用SpanQuery 时,此项配置会影响匹配的结果集

    field的定义需注意一下:

    1、将所有只用于搜索的,而不需要作为查询结果的field(特别是一些比较大的field)的stored设置为false。

    2、将不需要被用于搜索的,而只是作为查询结果返回的field的indexed设置为false。

    3、删除所有不必要的copyField声明,根据需要决定是否进行存储。

    4、为了索引字段的最小化和搜索的效率,将所有的 text fields的index都设置成false,然后使用copyField将他们都复制到一个总的 text field上,然后对他进行搜索。

    field 里还有两个域,是 Solr 扩展的,在 Lucene 中没有的概念,即dynamicField 动态域和 copyField 复制域

    正常数据结构一个是需要考虑中文分词,二个是考虑是否索引,是否分词,是否存储等等。下面的示范用到了三种类型的数据:

    1、字段需要分词、需要索引、需要存储,如:网页中的标题、内容等字段。

    2、字段需要索引,但不需要分词,需要存储,如:网页的发布时间等内容。

    3、字段不需要索引,不需要分词,但需要存储,如:引用的图片位置。

  

    配置实例:

<schema name="test" version="1.6">
  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
<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>
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<fieldType name="text_cn" class="solr.TextField">
    <analyzer type="index">
    <tokenizer class="com.hankcs.lucene.HanLPTokenizerFactory" enableIndexMode="true"/>
    </analyzer>
    <analyzer type="query">
    <!-- 切记不要在query中开启index模式 -->
    <tokenizer class="com.hankcs.lucene.HanLPTokenizerFactory" enableIndexMode="false"/>
     </analyzer>
    </fieldType> <!--下面三个字段需要分词,索引,存储 -->
<!-- 发布者 -->
<field name="webUser" type="text_cn" indexed="true" stored="true"/>
<!-- 标题 -->
<field name="webTitle" type="text_cn" indexed="true" stored="true" termVectors="true" termPositions="true" termOffsets="true"/>
<!-- 内容 -->
<field name="webContent" type="text_cn" indexed="true" stored="true" termVectors="true" termPositions="true" termOffsets="true"/> <!--下面需要索引,不分词,需要存储 -->
<!-- 来源ID -->
<field name="webId" type="int" indexed="true" stored="true"/>
<!-- 主键ObjectID -->
<field name="objectId" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<!-- 论坛类型(txt/pic/video) -->
<field name="webType" type="string" indexed="true" stored="true"/>
<!-- 发布时间 -->
<field name="webTime" type="date" indexed="true" stored="true"/> <!--下面信息仅存储 -->
<!-- 网站描述 -->
<field name="webCommit" type="string" indexed="false" stored="true"/>
<!-- 网址 -->
<field name="webUrl" type="string" indexed="false" stored="true"/>
<!-- 生成网页地址 -->
<field name="webHtml" type="string" indexed="false" stored="true"/>
<!-- 视频 -->
<field name="webVideo" type="string" indexed="false" stored="true"/>
<!-- 图片 -->
<field name="webImage" type="string" indexed="false" stored="true" multiValued="true"/> <!--下面信息为区别数据类型,索引,不分词,存储 -->
<!-- 索引类型,bbs/news/blog -->
<field name="indexType" type="string" indexed="true" stored="true"/>
<!-- 拷贝字段 ,索引不存储 -->
<field name="text" type="text_mm4j" indexed="true" stored="false" multiValued="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/> <copyField source="webUser" dest="text"/>
<copyField source="webTitle" dest="text"/>
<copyField source="webContent" dest="text"/> <uniqueKey>objectId</uniqueKey> <defaultSearchField>text</defaultSearchField> <solrQueryParser defaultOperator="OR"/> </schema>

  

  3、动态字段dynamicField

    动态域的属性配置跟普通的 field 类似,唯一有点区别就是 name 的属性值,可以用通配符,这样就可以模糊匹配多个域啦,这样设计的目的就是不用频繁的去修改我们的 schema.xml 中的

   field 配置去增加 field 域啦,比如之前有个 link_s域,某一天你想再增加一个 url_s 域,那你就需要去修改 schema.xml 配置文件,由于schema.xml 修改过后需要重启 tomcat 才能生效,重启即意味着程序的中断,

  这往往是不可接受的。所以引入动态域来避免频繁添加修改域,但前提是你的域需要符合你提前定义的动态域的域名称命名规则。

  

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

  4、冗余复制字段copyField

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

    假如有一个文章schema,一开始业务系统搜索的时候主要是搜索文章的内容,后来我希望搜索的时候能同时去搜索文章的标题,使用copyField,将标题和内容冗余为一个字段。

    

<field name="title" type="text_general" indexed="true" stored="true"/>
<field name="content" type="text_general" indexed="true" stored="true"/>
<copyField source="title" dest="text"/>
<copyField source="content" dest="text"/>

    

    拷贝字段就是查询的时候不用再输入:title:张三 and content:张三的个人简介。直接可以输入"张三"就可以将“名字”含“张三”或者“简介”中含“张三”的查询出来。他将需要查询的内容放在了一个字段中,

  并且默认查询该字段设为该字段就行了。

    要注意的是,如果你只是复制单个域,那么如果你被复制域本身就是多值域,那么目标域也是多值域,这毋庸置疑,那如果你复制的是多个域,只要其中有一个域是多值域,那么目标域就一定是多值域,这点一定要谨记。

  field 说完了,接着说说 fieldType 元素,它用来定义域类型, solr 内置的域类型有StrField , BoolField , TrieIntField , TrieFloatField , TrieLongField ,TrieDoubleField , TrieDateField , BinaryField , RandomSortField ,

  TextField等,其他更多域类型请自己查阅 Solr API 文档。

  5、常规Field Type设置

 <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>

    

    1、StrField: 这是一个不分词的字符串域,它支持 docValues 域,但当为其添加了docValues 域,则要求只能是单值域且该域必须存在或者该域有默认值

    2、BoolField : boolean 域,对应 true/false

    3、TrieIntField, TrieFloatField, TrieLongField, TrieDoubleField 这几个都是默认的数字域, precisionStep 属性一般用于数字范围查询, precisionStep 值越小,则索引时该域的域值分出的 token 个数越多,

      会增大硬盘上索引的体积,但它会加快数字范围检索的响应速度, positionIncrementGap 属性表示如果当前域是多值域时,多个值之间的间距,单值域,设置此项无意义。

    4、TrieDateField :显然这是一个日期域类型,不过遗憾的是它支持 1995-12-31T23:59:59Z 这种格式的日期,比较坑爹,为此我自定义了一个 TrieCNDateField 域类型,

      用于支持国人比较喜欢的 yyyy-MM-dd HH:mm:ss 格式的日期。源码请参见我的上一篇博客。

    5、BinaryField :经过 base64 编码的字符串域类型,即你需要把 binary 数据进行base64 编码才能被 solr 进行索引。

    6、RandomSortField :随机排序域类型,当你需要实现伪随机排序时,请使用此域类型。

    7、TextField :是用的最多的一种域类型,它需要进行分词,所以它一般需要配置分词器。至于具体它如何配置 IK 分词器,这里就不展开了。

    field type是对field类型的详细描述:

    1、name:类型的名称,对应field中的type

    2、class:类型对应的java对象, solr默认提供大概20多种类型

    3、positionIncrementGap:当field设置multValued为true时,用来分隔多个值之间的间隙大小

    4、autoGeneratePhraseQueries:有点类似找近义词或者自动纠错的设置,例如可以将 wi fi自动转为 wifi或wi-fi,如果不设置这个属性则需要在查询时强制加上引号,例如 ‘wi fi’ 。

    fieldType 元素还有一些额外的属性也需要注意下,比如sortMissingFirst,sortMissingLast 等:

      1、sortMissingLast 表示如果域值为 null, 在根据当前域进行排序时,把包含 null 值的document 排在最后一位

    2、sortMissingFirst :与 sortMissingLast 对应的,不言自明了,你应该懂的

    3、docValues :表示是否为 docValues 域,一般排序, group,facet 时会用到docValues 域。

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

    和进行查询的时候要使用的分析器analyzer,包括分词和过滤:

    例如:

    

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymGraphFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
<filter class="solr.FlattenGraphFilterFactory"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

    在index的analyzer中使用 solr.WhitespaceTokenizerFactory这个分词包,就是空格分词,然后使用 solr.StopFilterFactory,solr.WordDelimiterFilterFactory,solr.LowerCaseFilterFactory,

    solr.EnglishPorterFilterFactory,solr.RemoveDuplicatesTokenFilterFactory 这几个过滤器。在向索引库中添加text类型的索引的时候,Solr会首先用空格进行分词,然后把分词结果依次使用指定的过滤器进行过滤,

    最后剩下的结果才会加入到索引库中以备查询。Solr的analysis包并没有带支持中文分词的包。

  6、uniqueKey 元素

    最后需要说的就是 uniqueKey 元素,它用来配置 document 的唯一标识域,即 solr是用此域来决定增量导入时是否重复导入,如果 id 一样,则不会重复导入,或者当你更新索引时,你可以根据指定的 uniqueKey 域,

    来确定一个 document ,然后对该document 进行更新。总之,它是用来唯一确定一个 document 的,跟数据库表里的主键 id 概念类似,前提是你 uniqueKey 里配置的域名称你需要提前使用 field 元素进行定义。

    schema.xml里有一个uniqueKey,的配置,这里将id字段作为索引文档的唯一标识符,非常重要。

  参考:https://www.cnblogs.com/zhoujg/archive/2015/12/17/5053789.html

Solr 中 Schema 结构说明的更多相关文章

  1. Solr中Schema.xml中文版

    <?xml version="1.0" encoding="UTF-8" ?> <!-- Licensed to the Apache Sof ...

  2. Solr中schema.xml的解释

    接Solr-4.10.2与Tomcat整合.schema.xml位于D:\solr\data\solr\collection1\conf\中.1.fieldType节点    name: FieldT ...

  3. Solr 06 - Solr中配置使用IK分词器 (配置schema.xml)

    目录 1 配置中文分词器 1.1 准备IK中文分词器 1.2 配置schema.xml文件 1.3 重启Tomcat并测试 2 配置业务域 2.1 准备商品数据 2.2 配置商品业务域 2.3 配置s ...

  4. Solr:Schema设计

    本文已挪至  http://www.zhoujingen.cn/blog/8546.html Solr将数据以结构化的方式存入系统中,存储的过程中可以对数据建立索引,这个结构的定义就是通过schema ...

  5. 在Solr中配置和使用ansj分词

    在上一节[编译Ansj之Solr插件]中介绍如何编译ansj分词在solr(lucene)环境中使用的接口,本章将介绍如何在solr中使用ansj,其步骤主要包括:下载或者编译ansj和nlp-lan ...

  6. Solr中初学Demo

    import java.util.Collection; import java.util.Date; import org.apache.solr.client.solrj.SolrQuery; i ...

  7. Solr 08 - 在Solr Web管理页面中查询索引数据 (Solr中各类查询参数的使用方法)

    目录 1 Solr管理页面的查询入口 2 Solr查询输入框简介 3 Solr管理页面的查询方案 1 Solr管理页面的查询入口 选中需要查询的SolrCore, 然后在菜单栏选择[Query]: 2 ...

  8. 如何将数据库中的数据导入到Solr中

    要使用solr实现网站中商品搜索,需要将mysql数据库中数据在solr中创建索引. 1.需要在solr的schema.xml文件定义要存储的商品Field. 商品表中的字段为: 配置内容是: < ...

  9. 在Solr中配置中文分词IKAnalyzer

    李克华 云计算高级群: 292870151 交流:Hadoop.NoSQL.分布式.lucene.solr.nutch 在Solr中配置中文分词IKAnalyzer 1.在配置文件schema.xml ...

随机推荐

  1. oracle11g如何创建数据库

    oracle11g创建数据库的步骤如下:1.按住键盘上Windows键,打开开始菜单,找到Database Configuration Assitant并打开:2.打开数据库配置助手Database ...

  2. sql server 2008 R2无法连接127.0.0.1报错 Server error:40(错误:53)

    在公司用sql server 2008 R2很好的,回家连接127.0.0.1就报错.sql server2008R2主机名和.都可以登录,连接127.0.0.1出错,在与 SQL Server 建立 ...

  3. Longest Substring Without Repeating Characters——经典题

    Given a string, find the length of the longest substring without repeating characters. For example, ...

  4. Delphi获取毫秒级时间戳

    function GetJavaTime( d: TDateTime ): Int64; var dJavaStart: TDateTime; begin //java里的时间是从1970年1月1日0 ...

  5. 创建 OpenStack云主机 (十五)

    创建过程 创建虚拟网络 创建m1.nano规格的主机(相等于定义虚拟机的硬件配置) 生成一个密钥对(openstack的原理是不使用密码连接,而是使用密钥对进行连接) 增加安全组规则(用iptable ...

  6. UVA 548.Tree-fgets()函数读入字符串+二叉树(中序+后序遍历还原二叉树)+DFS or BFS(二叉树路径最小值并且相同路径值叶子节点权值最小)

    Tree UVA - 548 题意就是多次读入两个序列,第一个是中序遍历的,第二个是后序遍历的.还原二叉树,然后从根节点走到叶子节点,找路径权值和最小的,如果有相同权值的就找叶子节点权值最小的. 最后 ...

  7. zookeeper,hadoop安装部署其实与防火墙无关

    网上查看了很多人关于hadoop,zookeeper的文章,大多都把关闭防火墙作为首要前提,个人觉得这大可不必. 首先你需要知道你部署的是什么东西,它需要哪些端口即可.把相关端口打开就可以了啊.然后把 ...

  8. 【Kruskal】Slim Span

    [Uva1395]Slim Span 题目略…… 试题分析:codevs1001舒适的路线上加一个判一下连通性就好,顺便把除改成减 代码: #include<iostream> #incl ...

  9. 【LIS】【递推】Gym - 101246H - ``North-East''

    x坐标排序,y坐标当权值,同一个x坐标的,y从大到小排. 求f(i)表示以i结尾的LIS以后,从后向前枚举,不断更新一个max数组,max(i)代表最长上升子序列为i时,当前的 结尾的最大值是多少. ...

  10. 【区间dp】【四边形不等式】CDOJ1653 最小生成树?

    四边形不等式优化的资料去网上找下吧!很多. 可以证明,这个题里面,合并的代价满足较小区间+较大区间<=交错区间. 可以自己画个图看看. #include<cstdio> #inclu ...