sphinx 1.10-实时索引 api

/*
* @todo : sphinx实时索引curd操作类,适应sphinx 1.10-beta版
* @created :Wed Nov 10 10:38:27 CST 2010
* @email:[email protected]
* @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 ;
    }

}
?>
时间: 2024-08-11 03:38:18

sphinx 1.10-实时索引 api的相关文章

sphinx架构设计 -- 高并发rt实时索引

CleverCode最近在研究sphinx使用rt实时索引,总结了一下php调用的过程,并且总结了一下rt分布式架构设计. 1 安装Sphinx 安装详解请查看:http://blog.csdn.net/clevercode/article/details/52204124. 2 配置rt索引文件 vim /usr/local/sphinx2/etc/realtime.conf index username { # 实时索引类型 type = rt # 索引保存路径,平时都是保存在内存内,数据量

sphinx实时索引和高亮显示

sphinx实时索引和高亮显示 时间 2014-06-25 14:50:58  linux技术分享 -欧阳博客 原文  http://www.wantlearn.net/825 主题 Sphinx数据库 上次介绍了coreseek与sphinx的区别,并详细记录了安装coreseek文档说明,以及给php加上sphinx模块,详细内容请参考我写的coreseek详解这篇文档,这次主要介绍sphinx是如何做到实时索引.首先配置进入到coreseek配置文件目录,对原始配置文件进行配制,这里介略说

Sphinx 实时索引

index rt { type = rt rt_mem_limit = 512M path = /usr/local/sphinx/data/rt rt_field = title rt_field = content rt_attr_uint = gid } searchd { workers = threads listen = 3312 listen = 3313:mysql41 log = /usr/local/sphinx/var/log/searchd.log query_log =

Elasticsearch6.x indices apis(索引api)

1.索引api indices apis 用于管理索引划分,索引设置,索引别名,字段映射,索引模板 index management 1.1 create index 创建索引,可以指定设置和字段映射,也可以不指定,甚至可以省略创建索引过程,es会自动创建,示例: curl -X PUT "localhost:9200/test" -H 'Content-Type: application/json' -d' { "settings" : { "numbe

coreseek实时索引全文搜索

工作流程: 安装coreseek(win32版) 建立一个实时索引配置文件 根据配置文件开启searchd服务器 向mysql数据库实时插入数据 启动python客户端访问和搜索 安装coreseek(win32版) 官网下载:http://www.coreseek.cn/products-install/install_on_windows/ 这里的版本为4.0.1 建立实时索引配置文件 解压后,在etc目录下新建一个csft_rt.conf文件 写入如下配置: #实时索引配置文件 index

Coreseek:部门查询和增量索引代替实时索引

1.行业调查 索引系统需要通过主查询来获取所有的文档信息,一个简单的实现是整个表的数据到内存,但是这可能会导致整个表被锁定,并且使其它操作被阻止(例如:在MyISAM格款式上INSERT操作).同时,会浪费大量的内存来存储查询结果.喜欢它的问题. 为了避免出现这样的情况.CoreSeek/Sphinx支持一种被称为 区段查询的技术. 首先,CoreSeek/Sphinx从数据库中取出文档ID的最小值和最大值.将由最大值和最小值定义自然数区间分成若干份,一次获取数据.建立索引.现举比例如以下: s

Coreseek:区段查询及增量索引代替实时索引

1.区段查询 索引系统需要通过主查询来获取全部的文档信息,一种简单的实现是将整个表的数据读入内存,但是这可能导致整个表被锁定并使得其他操作被阻止(例如:在MyISAM格式上的INSERT操作),同时,将浪费大量内存用于存储查询结果,诸如此类的问题吧. 为了避免出现这种情况,CoreSeek/Sphinx支持一种被称为 区段查询的技术. 首先,CoreSeek/Sphinx从数据库中取出文档ID的最小值和最大值,将由最大值和最小值定义自然数区间分成若干份,一次获取数据,建立索引.现举例如下: sq

基于lucene的案例开发:实现实时索引基本原理

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/43982653 http://www.llwjy.com/blogd.php?id=63d4c488a2cccb5851c0498d374951c9 个人的博客小站也搭建成功,网址:www.llwjy.com/blog.php ,欢迎大家来吐槽~ 基本原理 在前面的博客中也说过,程序初始话索引文件是十分消耗系统资源的,因此要想实现实时索引就不能实时的去修改索引文件.重新加载索引文

搜索引擎系列十:Solr(solrj 、索引API 、 结构化数据导入)

一.SolrJ介绍 1. SolrJ是什么? Solr提供的用于JAVA应用中访问solr服务API的客户端jar.在我们的应用中引入solrj: <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>7.3.0</version> </dependency> 2. SolrJ的核