当前位置:编程问答 > SQLite >

走进全文搜索(PHP+SQLite) 三

答案:

可以看到注释掉的信息,是mb_函数部分,我去掉他们,一方面是为了迁移,一方面是mb_很慢。我偷懒地使用了不完整的UTF8切字,只判断2个字节的和3个字节的,其实只有UTF3,呵呵……以后再说。

CODE:
[Copy to clipboard]
<?php
function _normalize_text ($text)
 {
  
$symbol '`~!@#$%^&*()_+=|{}[]:;"<>,.?';
  
$symbol preg_quote ($symbol);
  
$ret preg_replace ("/[$symbol]/"' '$text);
  
$ret preg_replace ("/[rnt]/"' '$ret);
  
  
// For Chinese...
  
$ret str_replace ('“'' '$ret);
  
$ret str_replace ('”'' '$ret);
  
$ret str_replace ('‘'' '$ret);
  
$ret str_replace ('’'' '$ret);
  
$ret str_replace ('!'' '$ret);
  
$ret str_replace ('?'' '$ret);
  
$ret str_replace ('。'' '$ret);
  
$ret str_replace (','' '$ret);
  
$ret str_replace ('、'' '$ret);
  
$ret str_replace ('·'' '$ret);
  
$ret str_replace ('('' '$ret);
  
$ret str_replace (')'' '$ret);
  
$ret str_replace ('#'' '$ret);
  
$ret str_replace ('《'' '$ret);
  
$ret str_replace ('》'' '$ret);
  
$ret str_replace (';'' '$ret);
  
$ret str_replace (':'' '$ret);
  
$ret str_replace ('……'' '$ret);
  
$ret str_replace (' '' '$ret);
  
$ret str_replace ('——'' '$ret);
  
  
// Cut Words...
  
$ret str_replace ('的''的 '$ret);
  
$ret str_replace ('是''是 '$ret);
  
$ret str_replace ('吗''吗 '$ret);
  
$ret str_replace ('吧''吧 '$ret);
  
$ret str_replace ('呀''呀 '$ret);
  
  
$ret preg_replace ("/s+/"' '$ret);
  
  return (
trim ($ret) . ' ');
 }
?>

上面这个函数对文字做了一些简单的预处理,扔掉了一些标点符号,主要就是为了把文章先分割成“句子”,实验性函数……
    我的词典是保存在内存中的,依靠memcached来维护,每一个词保存的就是一个名字为word_key,值为“t”的内存变量。memcached对这个词典进行了有效的散列。下面是词典class:

CODE:
[Copy to clipboard]
<?php
class BsmSearchDictMemcached
{
 var 
$mc;
 
 function 
BsmSearchDictMemcached ()
 {
  global 
$dict_memcached_host$dict_memcached_port;
  
  
$this->mc memcache ();
  
$this->mc->add_server ($dict_memcached_host$dict_memcached_port);
  
  return 
$this->mc;
 }
 
 function 
make_mem_dict ()
 {
  global 
$dict_source_file;
  
  
$fp fopen ($dict_source_file'rb');
  
  while (
$word fgets ($fp)) {
   
$word trim ($word);
   
$key $this->_gen_mem_key ($word);
   
$this->mc->set ($key't');
  }
  
  
fclose ($fp);
 }
 
 function 
find ($word)
 {
  
$key $this->_gen_mem_key ($word);
  
  if (
$this->mc->get ($key) == 't')
   return 
true;
  
  else
   return 
false;
 }
 
 function 
_gen_mem_key ($word)
 {
  if (
$word) {
   
$md5_word md5 ($word);
   
$key substr ($md5_word04) . substr ($md5_word168);
   
$key 'dict_' $key;
  }
  
  else
   
$key 'NO_KEY';
  
  return 
$key;
 }
}
?>

一些参数是在BSM的配置文件中定义的,make_mem_dict是生成内存词典的方法,它从原始词典dict.dat中导出数据插入到内存中。
    一个使用实例:

CODE:
[Copy to clipboard]
<?php
define 
('IN_BSM'true);
$phpEx 'php';
error_reporting (2047);
require (
'../include/kernel/common.inc.' $phpEx);
require (
$include_root 'search/search.inc.' $phpEx);
$search = new BsmSearch ('search/');
$str '我是大傻瓜';
$start_time array_sum (explode (' 'microtime()));
$db->sql_query ("INSERT INTO `data` SET `text` = '$str');
$id = $db->sql_nextid ();
$search->add_text ($id, $str);
print_r ($search->search ('傻瓜'));
$end_time = array_sum (explode (' ', microtime()));
$time = $end_time - $start_time;
echo ('<br>Spend Time: ' . $time . ' secs');
?>

它在数据库里插入一篇内容叫“我是大傻瓜”的文章,同时创建了索引,然后搜索“傻瓜”这个词,结果会返回刚刚那个ID,如果之前还插入过包含“傻瓜”的文章,会一起返回。

    BsmSearch基本算是写了个框框,还有很多没有实现,我不着急,慢慢做。

上一个:sqlite3 遵循Python PDB-API 2.0 接口规范的SQLite库(1)
下一个:走进全文搜索(PHP+SQLite) 二

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,