邓世龙的自留地

兼济天下则达 独善其身则穷

月度归档: 2013年9月

关于Sphinx引擎的一些想法


最近一个星期都在看Sphinx搜索引擎的文档,并和组里的一个同事合作为公司的企业空间搜索建立索引,提供搜索服务,所以对于Sphinx有了一些了解,顺便几下来,以后用到了可以再看看。

先八卦一下,Sphinx首先是俄罗斯人Andrew Aksyonoff开发的全文搜索引擎,开源之后有其他人参与进来,功能更加强大了。俄罗斯人还是真是厉害,之前是Nginx,现在是Sphinx。可是Sphinx不支持中文,所以要下载Sphinxforchinese才可以用。

Sphinx的数据源主要来自数据库,如Mysql,这也是最常见的方式。以下主要写给公司配置引擎时的一些体会。

1.一般使用都是一个主索引和增量索引,主索引建立后一直不变,变化的是增量索引,搜索的结果为合并主索引和增量索引的搜索结果。每隔一段时间就到数据源中抓取数据,保存在一个tmp索引中,然后这个tmp索引和增量索引合并,当然也可以隔一段时间就将增量索引和主索引合并,但这个时间间隔最好长一些。

2.建索引需要的数据分布在许多个表上,所以要先写爬虫将这些表的数据从数据库中抓取出来,存到另一个表中。之后在Sphin的配置文件中,数据就可以来自这个新建的表。这个新建的表最好有一个自动变化的时间字段,也就是每次在这个表中插入数据或更新数据,这个时间自动都会变化,这个字段将用于增量索引。另外还需要建一个表来保存上一次抓取的时间,从这个时间往后,抓取新的数据。

3.默认情况下,从数据源中选出的数据都是建索引的。而默认情况下,对于建索引的数据,Sphinx将不会保存原始数据,如果需要Sphinx既建索引,又要保存数据,在配置文件中,将这个字段写为sql_field_string。对于时间类型,在sql_query中select数据时,就要用函数unix_timestamp将它转为整形的时间戳,在配置文件中,要将这个字段写为sql_attr_timestamp,这样在客户端中调用api转化时间时才会准确。

4.sql_query_post和sql_query_post_index是有区别的。前者是当Sphinx从数据库中得到数据后,立刻就会运行,而后者只有当索引真正成功建立后才会运行,这个区别还是很重要的。对于真正严格的程序,不应该在sql_query_pre和sql_query_post中更新增量时间,而应该在sql_query_post_index中更新增量时间。还有一个区别是sql_query_post和sql_query_post_index是存在与两个不同的tcp连接中,因为Sphinx从数据库中得到数据后去建索引,将会花费很长时间,所以它会将数据库连接关闭,等到索引建好之后,再去连接数据库,所以sql_query_post_index会在另一个连接中

5.对于可以使用id来做增量索引的数据,需要将这次增量的最大id保存到数据库中。一个很诱人的做法是,将这次增量的最大id保存在一个值中,然后在sql_query_post_index中将这个值保存到数据库中,这其实是不对的。因为上一条中说过,sql_query_post_index会在另一个连接中,所以之前连接中的值在这个连接中失效了。一个做法是将增量的最大id保存到数据库中一个tmp字段中,等到索引建成功后,在sql_query_post_index中,将这个最大id从数据库中读出,写到用于做增量索引的字段中。

6.事实上,比较难的一点是在于数据有更新的情况下,如何处理。当数据有更新时,在主索引中原来的数据将会失效,但是搜索时还是会搜到它。一个解决的办法是将原来的数据标示为删除,这就需要一个标示字段了。这个办法是我组长想出来的,在sql_query中就给它添加一个字段,标示未删除的。每次增量索引结束后,就通过每条记录的id(在Sphinx中,会给每条记录一个id),将主索引中相应的记录标示为删除。在搜索时,只需要搜索出标示为未删除的就可以了。对于官方文档中,我还没有看到如何解决这个问题的介绍。

7.如果能写一个程序来自动生成配置文件,那就再好不过了。上次我是手动输的,既容易出错,有耗眼力和精力。

整个过程最重要的还是将分布在多个表中的数据合并为一个表以及处理更新这两步上,如果能解决这两个问题,一个可用的全文搜索就完成了。暂时先写到这里,等以后有了新的体会再补充。

看来是我错了,文档中有说到数据更新这个问题,是用Klist,具体可以看文档。看Sphinx的源码很不舒服,因为可恶的匈牙利命名。

刺青(转)


今天下午窝在家里,于是上了饼干之屋,再次看了饼干写的刺青,饼干真是有个性,因为这篇文章,直接拜倒在饼干的石榴裙下,现在转载过来。

刺青

 不知道从什么时候开始,我就有了这种念头——刺青。

在中国大部分人看来,纹身是不被认同的,似乎它总是出现在一些被人们称之为邪恶势力和人物身上。对此我只能表示无奈,试问:何为恶,何又为善。

在我看来,刺青和胎记有着相似的功能——标志性。不过刺青却更胜一筹,他可以是个人情感、个性、信仰等的表现。胎记是与生俱来的,他的存在是没有经过疼痛感而来的,而且多半是成块状,无规则性。感性一点说他是你的上一世留下的纪念,或者他还有被寻找的可能,因为那是你与他人的约定。纹身可以自行选择图形,然后经过漫长的炙热感后,他形成了。

很多人会跟你说,谨慎纹身,至于为什么,百度一下你就知道了。我想我骨子里还是有股放荡不羁、固执的成分。喜欢跟大多数对着干,嗯,这叫做反社会意识化。

我们生活在社会这个围城里,我们的三观从小就被社会意识化了,我们做着人们认为对的事,废寝忘食、使出浑身解数去考取人们认为有前途的大学,然后报读了人们认为最具就业性的专业。哈哈,似乎从头到尾我们都是“被”接受,很恐怖,也很可悲,我们没有自己的想法,我们没有想过自己喜欢干什么,将来要过怎样的生活。可是我们还是这样的渡过了大学的时光。是的,大学他即将过完,是浑浑噩噩,是三点一线的生活,一个字“混”。他是胎记,因为他的存在不会让你有疼痛感,你感受不到他的存在。

我想社会就是那刺青,在他成形的过程中,你清清楚楚的感受到了疼、痛、无力感、挫败感,总之,终身难忘,百感交集。最重要的是,他无法抹去。