sphinx 索引的创建(一)

󰃭 2016-04-23

导读

上一篇我们安装好了sphinx, 这里面包含了几个工具, 其中的indexer 就是一个索引创建工具, 我们要使用它进行索引的创建

但在我们开始之前, 先说明几个概念

文档

在搜索中的文档的概念与一般的文档的概念略有不同, 搜索中的文档更多的是表示被搜索的数据记录, 比如数据库中的每条数据即对应一个文档。

索引

索引 既有可能表示一种数据结构, 同时也能表示这种数据结构的创建过程, 在下面我写的时候尽量不引起歧义, 如果有, 通过上下文可以判断是名词还是动词, 如果是名词, 就表示数据结构, 如果是动词, 就表示这种数据结构的创建

数据源

sphinx 的索引创建的数据源可以来自多个: sql数据库, 一般的文本文档, HTML文件,邮箱等等, 在sphinx 里, 所有的数据源都是结构化的数据, 类似数据库的字段和字段值, 每一条数据就对应一个文档.

我们即将要使用的是数据库的源

Full-text 字段

Full-text 字段,或者叫全文字段,是sphinx 要创建索引的文本字段, 搜索的时候的关键词就是要搜的这些字段的。

字段都是有名字的, 在sphinx中, 我们可以限制搜索的字段范围, 一个(比如只搜标题)或者多个(比如要同时搜标题和简介), sphinx 最多支持256个字段的搜索(version2.0.2)

sphinx 会将全文字段的文本内容获取后重新构造一种数据结构,即索引(名词), 通过索引, sphinx可以快速进行全文搜索。同时再创建好这个索引结构后, 就会丢弃原有的文本内容, 因为sphinx默认我们已经将文本内容保存在了某些地方(比如数据源的数据库中)

sphinx 在创建索引的时候还会忽略掉文本内容中的空格,大小写, 标点符号等等

属性字段

属性字段是用来进行文档过滤和排序的, 比如我们搜索某个类别下的文档, 我们需要对文档的类型进行过滤, 这个类型的字段就是属性字段, 同理, 如果我们需要将结果按照文档创建时间排序, 这个创建的时间字段也是一个属性字段

与全文字段不同, sphinx 的索引会保存属性字段的值, 但这些字段不能像全文字段一样被搜索, 而且这些字段是大小写敏感的

当前支持的属性字段的数据类型

  1. 无符号整型(1-2^32)
  2. unix 时间戳
  3. 浮点型数据
  4. 字符串
  5. Json数据
  6. MVA 多值属性

对Json类型数据和MVA 类型数据进行一下说明

Json类型

json 的数据一般表示的sql数据库源的字段中存储的json格式的数据, 这样,sphinx 就可以在有限的字段内进行更加灵活的过滤和排序了。

sphinx 在将这种类型数据创建到索引中的时候回忽略掉未被使用的json字段, 比如json存储了文章的点击量和被分享的数量值, 而我们仅需要使用点击量进行过滤和排序, 那我们索引创建的时候指定点击量作为属性字段, 且类型设置成sql_attr_json, 则分享的数据就能被直接忽略掉了

MVA 多值属性字段

这种字段允许我们进行多值过滤

一个应用场景: 我们的每篇文章都能打多个Tag(注意这里的tag存储的是tag_id, 后面会说明), 如果我们需要使用若干个tag_id 进行过滤, 那么我们就能将这个字段设置成sql_attr_multi, 创建好索引即可以进行这种过滤了

MVA 目前仅支持32位的无符号整型和64位的整型, 索引上面的Tag字段要想做这种过滤的话, 就只能以Tag_id 的类型存储多个tag了

值得注意的是, sphinx 会将匹配了任意一个tag_id 的文档返回, 比如某个文档的tag字段存储了2,7,11这几个tag_id, 而你传递了3,7 要进行过滤, 那么也能过滤出这个文档

而如果要通过这个tag字段进行Group的时候, 因为包含了多个tag_id, 就有可能返回多个包含了重复文档的记录。

索引类型

spphinx 中的索引有两个类型, 一种是disk index,一种是RT(realtime) index

disk index

暂且称其为磁盘索引, 这种索引可以快速创建和查询,同时内存占用还低, 但这种索引我们无法对其已存在的索引进行直接更新, 比如对其中的某个索引文档更改索引内容(不过可以倒是可以更新索引中的属性字段内容), 要想更新索引, 就只能一次性的重建整个磁盘索引

咋一看这个挺吓人的,但实际上,我们可以频繁的创建多个磁盘索引, 比如把某个磁盘索引分成多个, 仅重建最近更改最频繁的那个小的磁盘索引

RT index

real time index 又叫实时索引, 可以动态更新索引字段的值。新的索引内容可以在1ms 甚至更少的时间内被搜到, 不过有可能会偶尔导致数秒的卡顿(卡顿的时候索引服务依旧可用)

源数据限制

sphinx 对所有的源数据都有一个严格的限制

源数据的每个文档都必须有一个值唯一的字段,且要求是一个非0的正整型

如果不能满足这个限制条件, 就可能发生各种奇怪的事情和返回奇怪的结果

参考 sphinx官方文档