标签:
/* * @todo : sphinx实时索引curd操作类,适应sphinx 1.10-beta版 * @created :Wed Nov 10 10:38:27 CST 2010 * @email:blvming@gmail.com * @website:http://www.sphinxsearch.org * @author blvming * @version 1.0 * @example * * $sphinx = new SphinxRt(‘articleRt‘,‘127.0.0.1:9306‘); * //打开调试信息 * $sphinx->debug = true; * //查询 * $prodList = $sphinx->where($condition)->order($orderCondition)->group(‘prod_uid‘)->search(); * //插入数据 * $sphinxData[‘title‘] = $title; * $sphinxData[‘content‘] = $content; * $sphinx->insert($sphinxData); * */ class SphinxRt { private $_link; //sphinx 连接池 protected $_field = array(); //当前索引的字段属性 protected $_sql = array(); //sql表达式 protected $queryStr = ‘‘; //查询的sql public $rt = ‘‘ ; //當前索引 public $error = ‘‘; //最后的错误信息 public $debug = false; //调试状态 //构造函数 public function __construct($rt=‘‘,$host=‘192.168.1.10:9306‘) { try { $this->_link = mysql_connect($host); if(!$this->_link) { throw new Exception(‘sphinx 实时索引服务器连接失败!‘); } if($rt !=‘‘) { $this->rt = $this->_sql[‘rt‘] = $rt; } } catch (Exception $e) { $this->error = $e->getMessage(); } } /** +---------------------------------------------------------- * @todo 设置索引表 * @access public * @param param * @return void +---------------------------------------------------------- */ public function rt($rt) { $this->_sql[‘rt‘] = $this->rt = $rt; return $this; } /** +---------------------------------------------------------- * @todo where 匹配条件.注意:这里一定要主动加上where 关键词 不能出现这样的情况 where 1 * @access public * @param $where * @return void +---------------------------------------------------------- */ public function where($where) { $this->_sql[‘where‘] = ‘ where ‘.$where; return $this; } /** +---------------------------------------------------------- * @todo limit * @access public * @param param * @return void +---------------------------------------------------------- */ public function limit($limit) { $this->_sql[‘limit‘] = $limit; return $this; } /** +---------------------------------------------------------- * @todo option 评分权值设定等 * @access public * @param param * @return void +---------------------------------------------------------- */ public function option($option) { $this->_sql[‘option‘] = $option; return $option; } /** +---------------------------------------------------------- * @todo field * @access public * @param param * @return void +---------------------------------------------------------- */ public function field($field) { $this->_sql[‘field‘] = $field; return $this; } /** +---------------------------------------------------------- * @todo order * @access public * @param param * @return void +---------------------------------------------------------- */ public function order($order) { $this->_sql[‘order‘] = $order; return $this; } /** +---------------------------------------------------------- * @todo group * @access public * @param param * @return void +---------------------------------------------------------- */ public function group($group,$withGroup) { $this->_sql[‘group‘] = $group; if($group) { $this->_sql[‘withGroup‘] = $withGroup; } return $this; } /** +---------------------------------------------------------- * @todo 检索数据,并对数据进行排序,过滤,评分设定等 * @access public * @param param * @example select * from rt where match(‘keyword‘) group by gid WITHIN GROUP ORDER BY @weight DESC * order by gid desc limit 0,1 option ranker=bm25,max_matches=3,field_weights=(title=10,content=3); * @return array +---------------------------------------------------------- */ public function search() { //排序 if($this->_sql[‘order‘] != ‘‘) { $orderSql = ‘ ORDER BY ‘.$this->_sql[‘order‘]; } //分组聚合 if($this->_sql[‘group‘] !=‘‘) { $groupSql = ‘ GROUP BY ‘.$this->_sql[‘group‘]; //组内排序 if ($this->_sql[‘withGroup‘]!=‘‘) { $groupSql .= ‘ WITHIN GROUP ORDER BY ‘.$this->_sql[‘withGroup‘]; } } //附加选项 if($this->_sql[‘option‘] !=‘‘) { $optionSql = ‘ OPTION ‘.$this->_sql[‘option‘]; } //数量限制 if($this->_sql[‘limit‘]!=‘‘) { $limitSql = ‘limit ‘.$this->_sql[‘limit‘]; } //字段 if($this->_sql[‘field‘]==‘‘) { $field = ‘*‘; } else { $field= $this->_sql[‘field‘]; } if($this->_sql[‘where‘]!=‘‘) { $where = $this->_sql[‘where‘]; } else { $where =‘‘; } $this->queryStr = sprintf("SELECT %s FROM %s %s %s %s %s %s",$field,$this->_sql[‘rt‘],$where,$groupSql,$orderSql,$limitSql,$optionSql); $rs = $this->query(); if($rs) { $resArr = array(); while ($row = mysql_fetch_assoc($rs)) { $resArr[] = $row; } $resArr[‘meta‘] = $this->getMeta(); return $resArr; } return false; } /** +---------------------------------------------------------- * @todo 添加索引,注意,这里的添加并未考虑并发操作,可能在sphinx端会出现id冲突 * @access public * @param mixed $data 插入的数据 * @return bool +---------------------------------------------------------- */ public function insert($data,$lastId=0) { if(!empty($data)) { if($lastId===0) { $lastId = $this->getLastId(); } foreach ($data as $k=>$v) { $fields .= ‘,‘.$k; $values .= ",‘".$v."‘"; } $this->queryStr = "insert into ".$this->_sql[‘rt‘]."(id".$fields.") values ($lastId {$values})"; return $this->query(); } $this->error = ‘插入数据不能为空‘; return false; } /** +---------------------------------------------------------- * @todo 批量插入数据 * @access public * @param mixed $datas * @param boolean $asStr 是否使用逗号分隔的方式一次性插入 * @return void +---------------------------------------------------------- */ public function insertAll($datas,$asStr=true) { if(!empty($datas)) { $fields = ‘id‘; //字段 $values =‘‘; //值 $lastId = $this->getLastId(); $i = 0; foreach ($datas as $k=>$v) { //一次性插入数据,格式化 if($asStr) { $values .=‘,(‘.($i+$lastId); foreach ($v as $kk=>$va) { //属性字段 if($i==0) { $fields .= ‘,‘.$kk; } $values .= ",‘".$va."‘"; } $i++; $values .= ‘)‘; } else { $this->insert($v,$lastId); } } //批量数据sql格式化 if($asStr) { $values = ltrim($values,‘,‘); $this->queryStr = sprintf("insert into {$this->_sql[‘rt‘]}(%s) values %s",$fields,$values); return $this->query(); } } else { $this->error = ‘无效数据!‘; return false; } } /** +---------------------------------------------------------- * @todo 更新索引数据 * @access public * @param mixed $data 要更新的数据 * @param int $id 更新条件id * @return bool +---------------------------------------------------------- */ public function update($data,$id,$insert=true) { if(!empty($data) || $id>0) { //如果未找到记录且不需要不需要插入的话 if($insert ===false && $this->getById($id) ===false) return true; foreach ($data as $k=>$v) { $fields .= ‘,‘.$k; $values .= ",‘".$v."‘"; } //若该条数据不存在,直接插入 $this->queryStr = "replace into ".$this->_sql[‘rt‘]."(id".$fields.") values ($id{$values})"; return $this->query(); } $this->error = ‘无效更新数据!‘; return false; } /** +---------------------------------------------------------- * @todo 条件删除索引,如,根据外部id删除 * @access public * @param $condition * @return void +---------------------------------------------------------- */ public function delBy($condition) { $rs = $this->where($condition)->search(); if($rs) { foreach ($rs as $v) { if($v[‘id‘]) $idArr[] = $v[‘id‘]; } $this->delete($idArr); return true; } return false; } /** +---------------------------------------------------------- * @todo 删除索引数据,sphinx暂未提供批量删除的功能,如 in (123,34,565); * @access public * @param mixed $id * @return void +---------------------------------------------------------- */ public function delete($id) { if(is_array($id) && count($id)>=1) { $rs = true; foreach ($id as $v) { $this->queryStr = sprintf("delete from %s where id=%d",$this->_sql[‘rt‘],$v); $rs &= $this->query(); } } else { $this->queryStr = sprintf("delete from %s where id=%d",$this->_sql[‘rt‘],$id); $rs = $this->query(); } return $rs; } /** +---------------------------------------------------------- * @todo 清空表 * @access public * @return bool +---------------------------------------------------------- */ public function truncate() { $lastId = $this->getLastId(); for ($i=1;$i<=$lastId;$i++) { $this->delete($i); } return true; } /** +---------------------------------------------------------- * @todo 获取总记录 * @access public * @param param * @return void +---------------------------------------------------------- */ public function countAll() { $this->queryStr = "SELECT * FROM $this->_sql[‘rt‘] "; $this->query(); $meta = $this->getMeta(); if($meta) { return $meta[‘total_found‘]; } return false; } /** +---------------------------------------------------------- * @todo 获取当前最大值id,实现如mysql的auto_increment功能 * @access public * @param param * @return void +---------------------------------------------------------- */ public function getLastId() { $this->queryStr = "select * from {$this->_sql[‘rt‘]} order by id desc limit 1"; $rs = $this->query(); //若存在值,则取最大id的值,否则为1 $row = mysql_fetch_assoc($rs); if($row) { $lastId = $row[‘id‘]+1; } return $lastId?$lastId:1; } /** +---------------------------------------------------------- * @todo 获取查询状态值 * @access protected * @param param * @return array(); +---------------------------------------------------------- */ protected function getMeta() { $metaSql = "show meta"; $meta = mysql_query($metaSql); while ($row = mysql_fetch_assoc($meta)) { $metaArr[$row[‘Variable_name‘]] = $row[‘Value‘]; } return $metaArr; } /** +---------------------------------------------------------- * @todo 根据id获取记录 * @access public * @param int $id * @return array +---------------------------------------------------------- */ public function getById($id) { if($id>0) { $sql = "‘select * from $this->rt where id=".$id; $rs = mysql_query($sql); $row = mysql_fetch_assoc($rs); return $row; } return false; } /** +---------------------------------------------------------- * @todo 获取索引的字段值,前提条件是索引服务器中必须至少一个值,暂时没有api显示可以直接像mysql 的语句 desc table 来获取索引的字段; * @access public * @param param * @return void +---------------------------------------------------------- */ public function _getField($rt) { $rt = $rt?$rt:$this->rt; $this->queryStr = "select * from {$rt} limit 1"; $res = $this->query(); if($res) { $row = mysql_fetch_assoc($res); $field = array_keys($row); unset($field[1]); //去掉weight,这个字段是sphinx的权重值 return $field; } else { $this->error = ‘实时索引‘.$rt.‘没有任何记录,无法获取索引字段‘; return false; } } /** +---------------------------------------------------------- * @todo mysql查询 * @access public * @param param * @return void +---------------------------------------------------------- */ public function query($sql = ‘‘) { if($sql == ‘‘) { $sql = $this->queryStr; } if(!$this->_link) $this->triggerDebug($this->debug); $rs = mysql_query($sql,$this->_link); if(!$rs) $this->error = mysql_error(); $this->triggerDebug($this->debug); return $rs; } /** +---------------------------------------------------------- * @todo 获取错误信息 * @access public * @return string +---------------------------------------------------------- */ public function getError() { return $this->error; } /** +---------------------------------------------------------- * @todo 获取最后的sql语句 * @access public * @param param * @return string +---------------------------------------------------------- */ public function getLastSql() { return $this->queryStr; } /** +---------------------------------------------------------- * @todo 触发错误信息 * @access public * @param param * @return void +---------------------------------------------------------- */ public function triggerDebug($debugMode=false) { if($debugMode) { $debugInfo = debug_backtrace(); $errorStr = ‘file:‘.$debugInfo[0][‘file‘]; $errorStr .= ‘ line:‘.$debugInfo[0][‘line‘]; $errorStr .= ‘ sql:‘.$debugInfo[0][‘object‘]->queryStr; $errorStr .= ‘ error:‘.$debugInfo[0][‘object‘]->error.‘‘; if($debugInfo[0][‘object‘]->error!=‘‘)die($errorStr); echo ($errorStr); } return ; } } ?>
标签:
原文地址:http://www.cnblogs.com/Jerry-blog/p/5044970.html