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 '+好声 -声音';
中文分词+全文检索
PHP实现不依赖词典的"中文分词":
用PHP内置的SQLite引擎就能进行全文检索:
SQLite官方测试中,50多万条数据用LIKE '%keyword%'模糊搜索耗时22.5秒,用MATCH 'keyword'全文搜索仅耗时0.03秒,比模糊搜索快749倍.
其中分词表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,几乎不用任何配置,太容易了