php搜索实现

php开发过程中除了SQL中的like (不使用第三方) 有哪些比较有逼格的写法

感谢

阅读 3.3k
4 个回答

中文分词+全文检索

PHP实现不依赖词典的"中文分词":

function cws($str) {
    //找出字符串中的英文单词和数字
    if(preg_match_all('%[A-Za-z0-9_-]{2,}%', $str, $matches)) {
        $arr = $matches[0];
    }
    //以非中文(包括简体和繁体)进行正则分割
    $sections = preg_split('%[^\x{4e00}-\x{9fa5}]{1,}%u', $str);
    foreach($sections as $v) {
        if(preg_match_all('%[\x{4e00}-\x{9fa5}]%u', $v, $matches)) {
            //前后俩俩组合,实现冗余分词:如"中国好声音"将被分词为: 中国 国好 好声 声音
            $size = count($matches[0]);
            for($i = 0; $i <= $size-2; $i++) {
                $word = '';
                for($j = 0; $j < 2; $j++) {
                    $word .= $matches[0][$i+$j]; //echo $i.' '.$j.' '.$matches[0][$i+$j]."\n";
                }
                $arr[] = $word; //echo "\n";
            }
        }
    }
    return array_unique($arr);
}
$str = '中国好声音'; //原文字数为n,分词后的字数为2n-2,分词字数约为原文字数的2倍.
$arr = cws($str); //中文分词
var_export($arr); //array(0 => '中国', 1 => '国好', 2 => '好声', 3 => '声音')

用PHP内置的SQLite引擎就能进行全文检索:
SQLite官方测试中,50多万条数据用LIKE '%keyword%'模糊搜索耗时22.5秒,用MATCH 'keyword'全文搜索仅耗时0.03秒,比模糊搜索快749倍.

CREATE VIRTUAL TABLE post_fts USING fts4(content);
INSERT INTO post_fts(docid, content) VALUES(1, '中国 国好 好声 声音');
--包含其中一个关键词(注意OR为大写)
SELECT docid, content FROM post_fts WHERE content MATCH '好声 OR 声音';
--同时包含两个关键词
SELECT docid, content FROM post_fts WHERE content MATCH '好声 声音';
--包含"好声"但不包含"声音"
SELECT docid, content FROM post_fts WHERE content MATCH '+好声 -声音'; 

其中分词表post_fts里的docid对应数据表post里的id.
文章表post存储在MySQL,分词表post_fts存储在SQLite,互补影响.
SQLite的分词表post_fts可以实时构建,比如插入一条记录到MySQL的文章表时也相应插入一条记录到SQLite的分词表.也可以后台定时批量构建,这样就不会影响到正常的写入操作的请求响应速度了.

插入文章时,文件内容"中国好声音"被PHP分词为"中国 国好 好声 声音".
用户搜索时,输入"好声音",被PHP分词为"好声 声音".
然后就可以用上述SQL语句来对SQLite进行全文检索了.

SQLite图形化管理工具推荐开源跨平台的SQLiteStudio.

如果要提升SQLite读写性能,Linux上可能考虑把SQLite放到内存文件系统(tmpfs)/dev/shm里,这样就可以获得内存级别的IO速度.

补充:
segmentfault.com 用的是国人开源的全文检索服务XunSearch.
XunSearch提供了PHP的SCWS分词扩展和词库:
http://www.xunsearch.com/scws...

你说的这个不叫搜索,叫匹配like 是模糊匹配。

要实现真正的搜索,目前最佳的办法就是上 ElasticSearch,否则你打算用 PHP 自己实现一个搜索引擎?如果用 RDB 做搜索,无异是自杀行为。

关键词:Sphinx。
可以实现智能分词以及超级高效的搜索速度。
Sphinx的原理是提前把数据库的数据文件生成好索引,查询的时候直接经由Sphinx服务器进行调度。

用elasticsearch,配合laravel,几乎不用任何配置,太容易了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题