[参考Coreseek 全文检索服务器 2.0 (Sphinx 0.9.8)参考手册,详情见 http://www.coreseek.cn/docs/sphinx_doc_zhcn_0.9.pdf
]
3.1 数据源
索引数据是一个结构化的文档的集合,其中每个文档是字段的集合。
如果确有必要,一个索引的数据可以来自多个数据源。这些数据将严格按照配置文件中定义的顺序进行处理。所有从这些数据源获取到的文档将被合并,共同产生一个索引,如同他们来源于同一个数据源一样。
3.2 属性
属性是附加在每个文档上的额外的信息(值),可以在搜索的时候用于过滤和排序。目前支持的属性类型如下:
无符号整数(1-32 位宽)
UNIX 时间戳(timestamps)
浮点值(32 位,IEEE 754 单精度)
字符串叙述 (尤其是计算出的整数值);
多值属性 MVA(multi-value attributes)(32 位无符号整形值的变长序列).
3.3 多值属性 MVA
多值属性 MVA(multi-valued attributes)是文档属性的一种重要的特例,MVA 使得向文档附加一系列的值作为属性的想法成为可能。这对文章的 tags,产品类别等等非常有用。MVA 属性支持过滤和分组(但不支持分组排序)。目前 MVA 列表项的值被限制为 32 位无符号整数。列表的长度不受限制,只要有足够的RAM,任意个数的值都可以被附加到文档上(包含 MVA 值的.spm 文件会被 searchd 预缓冲到 RAM 中)
3.4 索引
目前在 Sphinx 中实现的唯一一种索引类型是为优化建立索引和检索的速度而设计的。随之而来的代价是更新索引相当的很慢。理论上讲,更新这种索引甚至可能比从头重建索引还要慢。不过大多数情况下这可以靠建立多个索引来解决索引更新慢的问题
3.5 源数据的限制
Sphinx 索引的源数据有一些限制,其中最重要的一条是: 所有文档的 ID 必须是唯一的无符号非零整数(根据 Sphinx 构造时的选项,可能是 32 位或64 位)
3.6 字符集、大小写转换和转换表
当建立索引时,Sphinx 从指定的数据源获得文本文档,将文本分成词的集合,再对每个词做大小写转换,于是“Abc”,“ABC”和“abc”都被当作同一个词(word,或者更学究一点,词项 term)为了正确完成上述工作,Sphinx 需要知道:
(1)源文本是什么编码的
(2)那些字符是字母,哪些不是
(3)哪些字符需要被转换,以及被转换成什么
3.7 SQL 数据源 (MySQL, PostgreSQL)
对于所有的 SQL 驱动,建立索引的过程如下:
(1)连接到数据库
(2)执行预查询,以便完成所有必须的初始设置,比如为 MySQL 连接设置编码
(3)执行主查询,其返回的的数据将被索引
(4)执行后查询,以便完成所有必须的清理工作
(5)关闭到数据库的连接
(6)对短语进行排序 (或者学究一点, 索引类型相关的后处理)
(7)再次建立到数据库的连接
(8)执行后索引查询,以便完成所有最终的清理工作
(9)再次关闭到数据库的连接
大多数参数是很直观的,例如数据库的用户名、主机、密码。不过,还有一些细节上的问题需要讨论。
分区查询:
Sphinx 需要通过主查询来获取全部的文档信息,一种简单的实现是将整个表的数据读入内存,但是这可能导致整个表被锁定并使得其他操作被阻止(例如:在 MyISAM 格式上的 INSERT操作),同时,将浪费大量内存用于存储查询结果,诸如此类的问题吧。为了避免出现这种情况,Sphinx 支持一种被称作“分区查询”的技术。首先,Sphinx 从数据库中取出文档 ID的最小值和最大值,将由最大值和最小值定义自然数区间分成若干份,一次获取数据,建立索引。
后查询(sql_post) vs. 索引后查询(sql_post_index):
后查询和索引后查询的区别在于,当 Sphinx 获取到全部文档数据后,立即执行后查询,但是构建索引的过程仍然可能因为某种原因失败。在另一方面,当索引后查询被执行时,可理所当然的认为索引已经成功构造完了。因为构造索引可能是个漫长的过程,因此对与数据库的连接在执行后索引操作后被关闭,在执行索引后操作前被再次打开。
3.8 xmlpipe 数据源
xmlpipe 数据源是处于让用户能够将现有数据嵌入 Sphinx 而无需开发新的数据源驱动的目的被设计和提供的。它将每篇文档限制为只能包括两个可全文索引的字段,以及只能包括两个属性。xmlpipe 数据源已经被废弃
3.9 xmlpipe2 数据源
数据模式,即数据字段和属性的完整列表,必须在任何文档被分析之前就确定。这既可以在配置文件中用 xmlpipe_field 和 xmlpipe_attr_xxx 选项指定,也可以就在数据流中用<sphinx:schema>元素指定。 <sphinx:schema>元素是可选的,但如果出现,就必须是<sphinx:docset>元素的第一个子元素。如果没有在数据流中内嵌的数据模式定义,配置文件中的相关设置就会生效,否则数据流内嵌的设置被优先采用。
xmlpipe2 可以识别的 XML 元素(标签)(以及前述元素可用的属性)如下:
(1)sphinx:docset 顶级元素,用于标明并包括 xmlpipe2 文档。
(2)Sphinx:schema 可选元素,它要么是 sphinx:docset 的第一个子元素,要么干脆不出现。声明文档的模式。包括数据字段和属性的声明。若此元素出现,则它会覆盖配置文件中对数据源的设定。
(3)Sphinx:field 可选元素,sphinx:schema 的子元素。声明一个全文数据字段。唯一可识别的属性是“name”,它指定了字段的名称,后续数据文档中具有此名称的元素的数据都被当作待检索的全文数据对待。
(4)sphinx:attr 可选元素,sphinx:schema 的子元素。用于声明具体属性。其已知的属性有:
● “name”,设定该属性名称,后续文档中具有该名称的元素应被当作一个属性对待。
● ”type”,设定该属性的类型。可能的类型包括“int”,“timestamp”,“str2ordinal”,“bool”和“float”
● “bits”,设定“int”型属性的宽度,有效值为 1 到 32
● “default”,设定该属性的默认值,若后续文档中没有指定这个属性,则使用此默认值。
(5)Sphinx:document 必须出现的元素,必须是 sphinx:docset 的子元素。包含任意多的其他元素,这些子元素带有待索引的数据字段和属性值,而这些数据字段或属性值既可以是用 sphinx:field和 sphinx:attr 元素声明的,也可以在配置文件中声明。唯一的已知属性是“id”,它必须包含一个唯一的整型的文档 ID。
3.10 实时索引更新
有这么一种常见的情况:整个数据集非常大,以至于难于经常性的重建索引,但是每次新增的记录却相当地少。一个典型的例子是:一个论坛有 1000000 个已经归档的帖子,但每天只有 1000 个新帖子。
在这种情况下可以用所谓的“主索引+增量索引”(main+delta)模式来实现“近实时”的索引更新。
这种方法的基本思路是设置两个数据源和两个索引,对很少更新或根本不更新的数据建立主索引,而对新增文档建立增量索引。增量索引更新的频率可以非常快,而文档可以在出现几分种内就可以被检索到。
确定具体某一文档的分属那个索引的分类工作可以自动完成。一个可选的方案是,建立一个计数表,记录将文档集分成两部分的那个文档 ID,而每次重新构建主索引时,这个表都会被更新。
3.11 索引合并
合并两个已有的索引比重新对所有数据做索引更有效率,而且有时候必须这样做(例如在“主索引+增量索引”分区模式中应合并主索引和增量索引,而不是简单地重新索引“主索引对应的数据)。因此 indexer 有这个选项。合并索引一般比重新索引快,但在大型索引上仍然不是一蹴而就。基本上,待合并的两个索引都会被读入内存一次,而合并后的内容需要写
入磁盘一次。例如,合并 100GB 和 1GB 的两个索引将导致 202GB 的 IO 操作(但很可能还是比重新索引少)
基本的命令语法如下:
indexer --merge DSTINDEX SRCINDEX [--rotate]
SRCINDEX 的内容被合并到 DSTINDEX 中,因此只有 DSTINDEX 索引会被改变。若DSTINDEX 已经被 searchd 用于提供服务,则--rotate 参数是必须的。初设计的使用模式是,将小量的更新从 SRCINDEX 合并到 DSTINDEX 中。因此,当属性被合并时,一旦出现了重复的文档 ID,SRCINDEX 中的属性值更优先(会覆盖 DSTINDEX 中的值)。不过要注意,“旧的”关键字并不会被自动删除。例如,在 DSTINDEX 中有一个叫做“old”的关键字与文档 123 相关联,而在 SRCINDEX 中则有关键字“new”与同一个文档相关,那么在合并后用这两个关键字都能找到文档 123。您可以给出一个显式条件来将文档从 DSTINDEX 中移除,以便应对这种情况,相关的开关是--merge-dst-range:
indexer --merge main delta --merge-dst-range deleted 0 0
这个开关允许您在合并过程中对目标索引实施过滤。过滤器可以有多个,只有满足全部过滤条件的文档才会在最终合并后的索引中出现。在上述例子中,过滤器只允许“deleted”为 0的那些条件通过,而去除所有标记为已删除(“deleted”)的记录(可以通过调用UpdateAttributes() 设置文档的属性)。