xunsearch增量索引改进版
最近测试了xunserach全文索引程序。xunsearch只有LINUX版,所以想用windows服务器请使用其它全文索引程序。xunsearch本身不像coreseek那样自带增量索引的功能,所以很多从coreseek转过来的朋友很是不习惯。不过xunsearch拥有很多的API和案例,使用这些程序很容易做出自己的增量索引脚本,只需要把这些脚本添加到LINUX服务器任务里就可以实现增量索引了。
下面是实现增量索引的PHP程序,修改好账号密码,索引sql语句后把这个文件添加到crontab任务里就可以。
1 <?php 2 /** 3 * 索引实时更新管理器 4 * 判断标准: 5 * 添加:pass_state=1 && create_time> 6 7 文件记录值 8 * 修改:pass_state=1 && edit_time> 文件记录值 9 * 删除:status =0 如果有del_time也可以通过上面的方法判断,我这里没有 10 * 文件记录值:上次更新索引时的时间 11 * 调用方法: 12 * 正常调用:jishubu.net.php 13 * 不开启日志:jishubu.net.php?log=no 14 * 删除日志的说明如下: 15 * 如果你是通过我这样记录已删除id的方式,并且非物理删除,并且开启了日志功能,第一次调用最好先在浏览器执行jishubu.net.php?first=yes,不然如果删除数据较多,生成的日志文件较多,浪费空间。 16 * 其他:然后把文件放到crontab中,每天,小时,或分执行一次就行了。请根据自己项目情况改进。 17 * @author www.jishubu.net on wish 2012.11.30 改进 18 */ 19 error_reporting(E_ALL ^ E_NOTICE); 20 define('APP_PATH',dirname(__FILE__)); 21 $prefix = '/usr/local/xunsearch'; 22 $element = "$prefix/sdk/php/app/mfnews.ini"; 23 require_once "$prefix/sdk/php/lib/XS.php"; 24 25 $first = (trim($_GET['first'])=='yes') ? true : false; 26 $log = (trim($_GET['log'])=='no') ? false : true; 27 28 $xs = new XS($element); // 建立 XS 对象 29 $index = $xs->index; // 获取 索引对象 30 $doc = new XSDocument; // 创建文档对象 31 32 //读取上次更新索引时间 33 $last_index_time = @file_get_contents(APP_PATH.'/last_index_time.txt'); 34 $last_index_time = $last_index_time ? $last_index_time : time(); //这里也可以在last_index_time.txt文件中加个初始值 35 //删除过的id列表,如果字段有删除时间字段则不需要记录,如果是物理删除,需要记录删除日志,否则无法知道哪些文件曾被删除 36 $last_del_id = @file_get_contents(APP_PATH.'/last_del_id.txt'); 37 38 $link = mysql_connect('localhost:3306', 'root', '123456') or exit(mysql_error()); 39 mysql_select_db('phpcms', $link) or exit(mysql_error()); 40 mysql_query("SET NAMES utf8"); 41 42 //查询总数据量,并分批更新 43 $sql = "select count(*) as zongshu from phpcms_news,phpcms_news_data where phpcms_news.id=phpcms_news_data.id and phpcms_news.status=99 and phpcms_news.islink=0 and (phpcms_news.inputtime > {$last_index_time} or phpcms_news.updatetime > {$last_index_time})"; 44 $zongshu = mysql_query($sql) or exit(mysql_error()); 45 46 while($row = mysql_fetch_array($zongshu, MYSQL_ASSOC)){ 47 $zx[]=$row; 48 } 49 50 $n=0; 51 $i = 1; $count=1; $add_total = 0; $edit_total=0;$addArray=array();$editArray=array(); 52 //添加分批查询避免查询出过多的数据使PHP报错 53 do{ 54 $index->openBuffer(); // 开启缓冲区 55 //增加,修改索引 56 $sql = "select inch_cms_news.id as id,title,url,inputtime,updatetime,phpcms_news_data.content as content from phpcms_news,phpcms_news_data where phpcms_news.id=phpcms_news_data.id and phpcms_news.status=99 and phpcms_news.islink=0 and (phpcms_news.inputtime > {$last_index_time} or phpcms_news.updatetime > {$last_index_time}) limit $n,100"; 57 $res = mysql_query($sql) or exit(mysql_error()); 58 $restult = array(); 59 60 while($row = mysql_fetch_array($res, MYSQL_ASSOC)){ 61 $row['title'] = preg_replace('/ |"/','',strip_tags($row['title'])); 62 $row['content'] = preg_replace('/ |"/','',strip_tags($row['content'])); 63 $edit_time = $row['updatetime']; $create_time = $row['inputtime']; 64 unset($row['updatetime']); 65 if($edit_time == $create_time){ 66 $add_total++; 67 $addArray[] = $row; 68 } else { 69 $edit_total++; 70 $editArray[] = $row; 71 } 72 $doc->setFields($row); 73 $index->update($doc); 74 $i++; 75 //如果回收站回收的数据,然后从已删除记录中,清除该id 76 if(strpos($last_del_id, ','.$row['id'].',')!==false){ 77 $last_del_id = str_replace($row['id'].',', '', $last_del_id); 78 } 79 } 80 $n=$n+100; 81 $index->closeBuffer(); // 关闭缓冲区 82 }while($n<=$zx['0']['zongshu']); 83 84 85 $index->openBuffer(); // 开启缓冲区 86 87 88 89 //删除索引 90 $sql = "SELECT phpcms_news.id as id,title,url,inputtime,phpcms_news_data.content as content FROM phpcms_news,phpcms_news_data where phpcms_news.id=phpcms_news_data.id and phpcms_news.status!=99 and phpcms_news.islink=0"; 91 $res = mysql_query($sql) or exit(mysql_error()); 92 $del_total = 0; $ids = ''; $delArray = array(); 93 while($row = mysql_fetch_array($res, MYSQL_ASSOC)){ 94 if(strpos($last_del_id, ','.$row['id'].',')===false){ 95 $ids .= $row['id'].','; 96 $delArray[] = $row; 97 $del_total++; 98 } 99 } 100 if($ids) { 101 $index->del(array(trim($ids,','))); 102 $last_del_id = $last_del_id ? $last_del_id.$ids : ','.$ids; 103 } 104 105 $index->closeBuffer(); // 关闭缓冲区 106 107 $total = $add_total + $edit_total + $del_total; 108 if($total){ 109 110 //记录索引更新时间 111 @file_put_contents(APP_PATH.'/last_index_time.txt', time()); 112 @file_put_contents(APP_PATH.'/last_del_id.txt', $last_del_id); 113 114 //记录日志 115 if($log){ 116 $currdate = date('Y-m-d H:i:s',time()); 117 if(!$first) @file_put_contents('/tmp/myindex_log.txt', "\n@@@@@@@@@@@@@@@@@@@@@ {$currdate} 本次更新{$total}条记录,详情如下:@@@@@@@@@@@@@@@@@@@@@@\n\n", FILE_APPEND); 118 if($add_total) addMyIndexLog('add', $add_total, $addArray); 119 if($edit_total) addMyIndexLog('update', $edit_total, $editArray); 120 if($del_total&&!$first) addMyIndexLog('delete', $del_total, $delArray); 121 } 122 } 123 124 function addMyIndexLog($logtype, $logtatal, $logdata, $prefix='') 125 { 126 @file_put_contents('/tmp/myindex_log.txt', $prefix.date('Y-m-d H:i:s',time()).' '.$logtype.' index num : '.$logtatal.' '.str_repeat('*', 50)."\n".print_r($logdata, true) , FILE_APPEND); 127 } 128 129 mysql_free_result($res); 130 mysql_close($link); 131 if($total) $index->flushIndex(); 132 ?>
程序保存文件为jishubu.net.php并在同一目录下新建last_index_time.txt
和last_del_id.txt
文件。
我添加的任务是每小时执行两次更新索引如下:
2,32 * * * * /usr/local/php/bin/php /web/jishubu.net.php