<solr in action>indexing个人笔记 solr的索引过程可概括为三个关键的任务: 1.转换一份文件从它的原始格式到支持的格式,如XML或者JSON 2.使用已定义好的其中一种接口的来添加此份文档,典型是HTTP POST 3.索引期间,配置Solr来应用转换到文档中的文本 见图15102701.jpg 设计方案 关于你的搜索应用,你要学会回答以下关键问题: 1.在你的索引中,文档是什么 2.每份文档的唯一键是如何被标识 3.在你的文档里,那些字段可以被用户搜索 4.在搜索结果,那几个字段应该显示给用户 问题一就是要讨论文档粒度. 问题二,找一个唯一字段标识每份文档,solr用来查找这份文档,如果带有同一唯一键的文档要添加到索引,solr会使用这份最后的文档覆盖已存在的记录. 问题三,那些字段是索引字段.除了用于搜索的字段外,还有用于排序,分面(facet),分组(group by),用于提供搜索建议或执行函数查询的字段都应该标记为索引字段 问题四,那些字段是存储字段.一般从搜索角度来看是没有用的,但用于显示搜索结果的字段,都可称为存储字段. schema.xml就是solr用于理解如何索引你的文档的主要配置文档.schema.xml文档主要有三部分. 1.<fields>元素包含<field>和<dynamicField>用于定义你的文档的基本结构. 2.其他元素.例如<uniqueKey>和<copyField>,它们列于<fields>元素之后. 3.<types>下的字段类型决定了日期,数字,文本在solr是如何被处理的 必须字段属性. <field name="screen_name" type="string" indexed="true" stored="true" /> 每个字段都要有一个唯一name属性,还有一个type属性.当一个字段是存储字段,solr存储原始值而不是分析后的值.如上面,此文本字段是可搜索的,也可以在搜索结果返回原始文本.当然,如果在搜索结果不返回这个字段,那么就必要存储这个字段 多值字段 如果用一个字段保存多个值来建立索引,就可以将这个字段设置multiValued="true" 动态字段 使用glob风格表达式匹配字段,以下情况可以使用动态字段: 1.使用多个字段建模文档<dynamicField name="*_s" type="string" indexed="true" stored="true" /> 2.从不同来源支持文档 3.添加新文档来源 复制字段 以下两种情况使用复制字体 1.将多个字段内容放入单个字段(multiValued="true"的来源的name都是一样的,而此情况的name是不一样的) 2.应用不同的文本分析同一个字段内容来创建一个新的搜索字段 结构化非文本字段类型 1.字符串字段.<fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/> solr.对应org.apache.solr.schema.包的缩写. 2.日期字段.<fieldType name="tdate" class="solr.TrieDateField" omitNorms="true" precisionStep="6" positionIncrementGap="0"/> 3.数字字段.<fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/> sortMissingFirst="true"排序结果中,solr将对于此字段没有值的文档列在结果的顶部. sortMissingLast="true"排序结果中,solr将对于此字段没有值的文档列在结果的底部. precisionStep="数字"在索引,决定创建词语的数目来代表数值做快速排序查询在那些基于Trie的字段.如TrieDate和TrieLong 数字越小,索引占空间越大,性能越好.所以在占空间越大和性能之间衡量取一个合适值. 使用xml或json索引文档. 对于动态字段,schema.xml有默认配置,使用以下使命令就OK cd $SOLR_IN_ACTION/example-docs/ java -jar post.jar ch5/tweets.xml 使用SolrJ客户端库添加文档 SolrServer solr = new HttpSolrServer(serverUrl); SolrInputDocument doc1 = new SolrInputDocument(); doc1.setField("id", "1"); doc1.setField("screen_name_s", "@thelabdude"); solr.add(doc1); SolrInputDocument doc2 = new SolrInputDocument(); doc2.setField("id", "2"); doc2.setField("screen_name_s", "@thelabdude"); solr.add(doc2); solr.commit(true, true); 其它工具导入文档到solr Data Import Handler (DIH)(外部源为网站或关系型数据库) ExtractingRequestHandler, aka Solr Cell(从二进制文件如PDf,MS Office,OpenOffice文档抽取文本建索引) Nutch(可以使用out of the box(开箱即用)的爬虫) 更新handler 请求类型 描述 xml例子 Add 添加一个或多个文档到索引<add><doc><field name="id">1</field>...</doc></add> Delete 根据ID删除文档<delete><id>1</id></delete> Delete by query 根据lucence查询删除文档<delete><query>screen_name:@thelabdude</query></delete> Atomic update 使用乐观锁更新已存在文档的一个或多个字段<add><doc><field name="id">1</field><field update="set"name="favorites_count">12</field></doc></add> Commit 提交文档到索引<commit waitSearcher="true" softCommit="false" /> Optimize 通过混合多个段和移除已删除优化索引<optimize waitSearcher="false"/> 正常提交也叫硬提交.solr刷新所以未提交文档到硬盘并且刷新内部叫搜索器的组件,以便最近提交的文档可被搜索.提交成功后,最近提交的文档安全地被持久化到长期存储. 软件提交.支持近实时搜索.你可以认为软提交作为一种机制使文档能近实时搜索,通过跳过硬提交耗资源多的方面,如刷新到长期存储. 你仍然需要在某个时间点做一个硬提交来确保未提交的文档最终被刷新到长期存储. 两者的区别就是有没有刷新到长期存储. AUTOCOMMIT(自动硬提交) 1.在一个指定的时间内提交每一份文档. 2.一旦到达用户指定未提交文档的阈值,提交所有文档. 3.在一个常规时间间隔,提交所有文档.如每十分钟. <autoCommit> <maxTime>600000</maxTime> <maxDocs>50000</maxDocs> <openSearcher>true</openSearcher> </autoCommit> autoSoftCommit(自动软提交) <autoSoftCommit> <maxTime>1000</maxTime> </autoSoftCommit> 事务日志的三个关键目的: 1.用于支持实时取和原子性更新. 2.从提交过程分离连续写 3.在SolrCloud支持同步复制到shard leaders update="值" 值可为set,inc,add set在我看来理解为覆盖,inc用于数值在原基础上递增,add用于添加多值(Multivalued) 使用_version_实现乐观锁控制之前必须要知道_version_值, 此值可通过get请求http://localhost:8983/solr/collection1/get?id=1&fl=id,_version_获取 (如果了解过JPA带有@Version字段的实体,使用乐观锁解决并发问题.上面的这种机制是一样的) 索引管理 索引存储.提交文档到索引时,是使用一个叫directory的组件写到长期存储.这个组件的四个好处: 1.从长期存储读和写到长期存储,隐藏细节. 2.实现一个特定存储锁机制来阻止索引中断 3.隔离Solr来自于从JVM和操作系统的特点。 4.启用扩展一个基于directory实现的行为来支持特定使用情况,如近实时搜索 默认存储配置solr.NRTCachingDirectoryFactory 它是StandardDirectoryFactory的封装,可以根据操作系统和jvm的具体情况,替换为MMapDirectory,SimpleFSDirectory,NIOFSDirectory三者之一. 段混合.这是一个很耗CPU,硬盘IO的操作.所以solr社区当前建议微调solr段混合策略,而不是混合成一个大文件.有需要再去看看专家级混合设置 处理已删除的文档.删除不会从已存在段删除文档.删除的文档并没有从索引中移除,而是直到包含删除文档的段被合并那时才是真的删除. |
|