文档章节

robbe+base64+Mysql简易有效的php全文索引实现

狮子的魂
 狮子的魂
发布于 2013/03/01 13:49
字数 1237
阅读 927
收藏 9

确实有很多方法来给php提供全文索引功能。


例如:

1。solr或者lucene,(需要安装对应的php客户端扩展)。

2。sphinx

3。基于任何一个数据库(key/value的最好)的模拟实现。

4。Mysql的全文索引。

5。自己给php加上全文索引扩展。(就因为这一点,可以说有太多的实现方法了)


本文要介绍的是第四种,使用MySQL的全文索引来实现php的全文检索功能。

一。前提

MySQL数据表引擎要是MyISAM (Mysql的ISAM索引结构的实现)


二。准备:

假设建立如下一个简易的文章表格:

+------+---------+-----------+--------------------------------------+
| Id   | title   | author    |  content    | c_idx(text,fulltext)      |
+------+---------+-----------+------------------------------------+

其中content为原文,c_idx为中文分词后的base64编码串接字符串,并且为fulltext索引。

请看下文。


三。实现分析:

1。如果要被检索的内容是英文的,那么要做的事情很简单,给要检索的字段加上一个fulltext索引就可以了。

2。如果被检索的内容是CJK字符集合或者是CJK和英文的混合的话那问题就来了。(我们都知道,MySQL的全文索引不支持中文分词)。

能不能把分词之后中文转换成英文呢?

对,我就是这么想的:

将文章内从content字段的内容进行中文分词,然后将得到的词条转换成英文,再将转换后的词条使用空格串接起来,写入数据库即可。

这需要解决两个问题:

(1).中文分词:

这是搜索引擎的难点之一。速度和准确率是其瓶颈所在。

这里我推荐本人的开源php中文分词扩展robbe,robbe是建立在开源高性能中文分词组建friso上的一个php扩展。也是鄙人的作品。分词速度和准确率都不错。

(2).将中文字符串转换成英文字符串:

使用什么编码呢?想来想去,试来试去,发现base64编码最适合了。(如果有发现更好的编码,请比吝赐教测叫,在此先谢了)。

base64的编码和解码速度都很快。

另外编码后的文本所占的空间比编码前的文本只多一点(比原来长1/3)。

(另外,base64编码后的字符串中可能会包含+和/字符,会影响要MySQL对英文分词,所系需要手动替换一下)


四。具体实现:

<?php
$content = $_POST['content'];  //过滤什么的,就是你的事情啦。

//1.使用复杂模式,对文本进行分词。
//@see robbe文档 https://code.google.com/p/robbe/wiki/RobbeFunctions
$_result = rb_split($content, __RB_COMPLEX_MODE__);

//2.进行base64编码,并且使用空格串接分词结果。
$_str = '';
foreach ( $_result as $_value ) {
    $_str .= ' '.base64_encode($_value);
}

//3.写入文本到fulltext数据表中。
?>


1.查询SQL:

select 字段列表 from #_table where Match(c_idx) Against(检索字符串);

或者:

select #_files, Match(c_idx) Against(检索字符串) AS rank from #_table order by rank

返回的结果是自动根据相关度排序的。

2.或者使用bool模式:

select #_files from #_table where Match(c_idx) Against(检索字符串 IN BOOLEAN MODE)

常用布尔操作符:

+    包含,词必须存在。

-    排除,词必须不出现。

>    包含,而且增加等级值

<    包含,而且减少等级值

()    吧词组合成一个表达式。

~    取消一个词的排序值。

*    词尾通配符。

""    定义一个短语。

例如:

select content from article where Match(c_idx) Against('+你好的base64编码字符串 +我们的base64编码字符串' IN BOOLEAN MODE)

查询包含你好和我们的记录。

-----------------------------------------------

select content from article where Match(c_idx) Against('你好的base64编码字符串 我们的base64编码字符串' IN BOOLEAN MODE)

查询至少包含“你好”和“我们”中的一个的记录。

-----------------------------------------------

select content from article where Match(c_idx) Against('“你好的base64编码字符串 我们的base64编码字符串”' IN BOOLEAN MODE)


搜索匹配短语:“你好 我们”

-----------------------------------------------

select content from article where Match(c_idx) Against('>你好的base64编码字符串 <我们的base64编码字符串' IN BOOLEAN MODE)

匹配“你好”和“我们”,并且增加“你好”的等级,减少“我们”的等级。

3.使用查询扩展:4.11或者更高版本才支持。

select #_files from #_table where Match(c_idx) Against(检索字符串 WITH QUERY EXPANSION)

五。效率分析:

对于一般数据来的网站,例如:个人博客,企业文章,新闻什么的,(60W以下的数据记录条数)

使用此方法可以比较好的解决搜索问题,但是数据量大时,并不是很好的解决办法。

30W的数据记录(平均大小10K),平均查询0.02sec的样子。还算不错吧。

索引的内容不一定是全文(即c_idx字段的内容),可以是人工筛选后的核心性词组合。那样可以达到更好的检索效果和更快的检索速度。

© 著作权归作者所有

共有 人打赏支持
狮子的魂

狮子的魂

粉丝 205
博文 11
码字总数 11922
作品 7
深圳
CEO
私信 提问
加载中

评论(2)

狮子的魂
狮子的魂

引用来自“blackfox”的评论

我又测试了以下,如果都把要查的字段都建索引的话,速度还能提升100多倍的样子。

没试过, 找个时间试下...
阳建
阳建
我又测试了以下,如果都把要查的字段都建索引的话,速度还能提升100多倍的样子。
skymvc开发简易搜素引擎

skymvc开发简易搜素引擎 /* 作者 雷日锦 2016-05-24 *大家好,欢迎学习。今天给大家讲一个简易搜索引擎的开发。 *搜索引擎分为两部分:蜘蛛 和 全文索引 *演示地址:http://skycms.deitui.co...

得推网络
2016/05/24
18
0
Lucene Index薄荷糖--LuciMint

LuciMint(Lucene Index薄荷糖)是一个基于Lucene的全文索引小组件,它封装了Lucene的底层对Document对象的操作,提供了一个面向用户数据格式的,轻量级的索引操作接口。 采用异步请求方式,L...

匿名
2012/03/30
1K
0
PHP面试之数据库—创建高性能索引

真题 简单描述MySQL中,索引、主键、唯一索引、联合索引的区别,对数据库的性能有什么影响? MySQL索引的基础和类型 索引:类似于书籍的目录,想找到一本书的某个特定的主题,需要先找到书的...

openoter
2018/04/19
0
0
Apache Lucene 5.0 发布,Java 搜索引擎

Apache Lucene 开始了一个全新的里程碑,发布了 5.0 版本。该版本包括更强大的安全索引,降低内存堆的使用。同时包含其他的小改进。详细的内容请看发行说明。完整的改进列表请看 Changes。下...

JPowerman
2015/02/26
3
0
基于mysql全文索引的深入理解

前言:本文简单讲述全文索引的应用实例,MYSQL演示版本5.5.24。 Q:全文索引适用于什么场合? A:全文索引是目前实现大数据搜索的关键技术。 至于更详细的介绍请自行百度,本文不再阐述。 ----...

pureboys
2014/12/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Vert.x系列(二)--EventBusImpl源码分析

前言:Vert.x 实现了2种完成不同的eventBus: EventBusImpl(A local event bus implementation)和 它的子类 ClusteredEventBus(An event bus implementation that clusters with other Ve......

冷基
31分钟前
0
0
Perl - 获取文件项目

参考:http://www.runoob.com/perl/perl-directories.html 下面返回JSON格式的文件列表 #!/usr/bin/perluse strict;use warnings;use utf8;use feature ':5.26';require Fi......

wffger
昨天
1
0
vue组件系列3、查询下载

直接源码,虽然样式样式不好看,逻辑也不是最优,但是可以留作纪念。毕竟以后类似的功能只需要优化就可以了,不用每次都重头开始。。。 <template> <div class="pre_upload"> <div ...

轻轻的往前走
昨天
1
0
java浅复制和深复制

之前写了数组的复制,所以这里继续总结一下浅复制和深复制。 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝。 深拷贝:对基本数据类型进行值传递,对引用数据类型,...

woshixin
昨天
1
0
kubernetes 二进制包安装

环境 角色 主机名 内网 IP 集群 IP 操作系统 服务 执行目录 部署机 k8s-master master120 10.0.4.120 - CentOS kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/ et......

Colben
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部