文档说明

XSIndex

XS
继承关系 class XSIndex » XSServer » XSComponent
版本 1.0.0
源代码 sdk/php/lib/XSIndex.class.php
XS 索引管理 添加/删除/修改索引数据

Public 属性

隐去继承来的属性

名称类型描述定义于
connString string 连接字符串 XSServer
customDict string 获取自定义词典内容 XSIndex
project string 获取当前项目名称 XSServer
respond XSCommand 从服务器读取响应指令 XSServer
scwsMulti int 获取当前索引库的分词复合等级 XSIndex
socket mixed 获取连接资源描述符 XSServer
xs XS 服务端关联的 XS 对象 XSServer

Public 方法

隐去继承来的方法

名称描述定义于
__construct() 构造函数, 打开连接 XSServer
__destruct() 析构函数 XSIndex
__get() 魔术方法 __get XSComponent
__isset() 魔术方法 __isset XSComponent
__set() 魔术方法 __set XSComponent
__unset() 魔术方法 __unset XSComponent
add() 添加文档到索引中 XSIndex
addExdata() 批量提交索引命令封包数据 XSIndex
addServer() 增加一个同步索引服务器 XSIndex
addSynonym() 添加同义词 XSIndex
beginRebuild() 开始重建索引 XSIndex
clean() 完全清空索引数据 XSIndex
close() 关闭索引服务端连接 XSIndex
closeBuffer() 提交所有指令并关闭缓冲区 XSIndex
del() 删除索引中的数据 XSIndex
delSynonym() 删除某个同义词 XSIndex
endRebuild() 完成并关闭重建索引 XSIndex
execCommand() 执行服务端指令并获取返回值 XSIndex
flushIndex() 强制刷新服务端的当前库的索引缓存 XSIndex
flushLogging() 强制刷新服务端当前项目的搜索日志 XSIndex
getConnString() Returns 连接字符串 XSServer
getCustomDict() 获取自定义词典内容 XSIndex
getProject() 获取当前项目名称 XSServer
getRespond() 从服务器读取响应指令 XSServer
getScwsMulti() 获取当前索引库的分词复合等级 XSIndex
getSocket() 获取连接资源描述符 XSServer
hasRespond() 判断服务端是否有可读数据 XSServer
open() 打开服务端连接 XSServer
openBuffer() 开启索引命令提交缓冲区 XSIndex
reopen() 重新打开连接 XSServer
sendCommand() 往服务器直接发送指令 (无缓存) XSServer
setCustomDict() 设置自定义词典内容 XSIndex
setDb() 更改存放索引数据的目录 XSIndex
setProject() 设置当前项目 XSServer
setScwsMulti() 设置当前索引库的分词复合等级 XSIndex
setTimeout() 设置服务端超时秒数 XSServer
stopRebuild() 中止索引重建 XSIndex
update() 更新索引文档 XSIndex

Protected 方法

隐去继承来的方法

名称描述定义于
check() 检测服务端的连接情况 XSServer
connect() 连接服务端 XSServer
read() 读取数据 XSServer
write() 写入数据 XSServer

属性明细

customDict 属性
public string getCustomDict()
public void setCustomDict(string $content)

获取自定义词典内容

scwsMulti 属性 (自版本 v1.4.7 起可用)
public int getScwsMulti()
public XSIndex setScwsMulti(int $level)

获取当前索引库的分词复合等级

参见

方法明细

__destruct() 方法
public void __destruct()
源码: sdk/php/lib/XSIndex.class.php#L528 (显示)
public function __destruct()
{
    if (
$this->_rebuild === true) {
        try {
            
$this->endRebuild();
        } catch (
Exception $e) {
            
        }
    }
    foreach (
self::$_adds as $srv) {
        
$srv->close();
    }
    
self::$_adds = array();
    
parent::__destruct();
}

析构函数 在此自动关闭开启的 rebuild

add() 方法
public XSIndex add(XSDocument $doc)
$doc XSDocument
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L72 (显示)
public function add(XSDocument $doc)
{
    return 
$this->update($doctrue);
}

添加文档到索引中 特别要注意的是: 系统不会自动检测主键是否冲突, 即便已存在相同主键也会添加进去

参见

addExdata() 方法
public XSIndex addExdata(string $data, bool $check_file=true)
$data string 要提交的命令封包数据, 或存储命令封包的文件路径, 编码必须已经是 UTF-8
$check_file bool 是否检测参数为文件的情况
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L253 (显示)
public function addExdata($data$check_file true)
{
    if (
strlen($data) < 255 && $check_file
            
&& file_exists($data) && ($data file_get_contents($data)) === false) {
        throw new 
XSException('Failed to read exdata from file');
    }

    
// try to check allowed (BUG: check the first cmd only):
    // XS_CMD_IMPORT_HEADER, XS_CMD_INDEX_REQUEST, XS_CMD_INDEX_REMOVE, XS_CMD_INDEX_EXDATA
    
$first ord(substr($data01));
    if (
$first != XS_CMD_IMPORT_HEADER
            
&& $first != XS_CMD_INDEX_REQUEST && $first != XS_CMD_INDEX_SYNONYMS
            
&& $first != XS_CMD_INDEX_REMOVE && $first != XS_CMD_INDEX_EXDATA) {
        throw new 
XSException('Invalid start command of exdata (CMD:' $first ')');
    }

    
// create cmd & execute it
    
$cmd = array('cmd' => XS_CMD_INDEX_EXDATA'buf' => $data);
    
$this->execCommand($cmdXS_CMD_OK_RQST_FINISHED);
    return 
$this;
}

批量提交索引命令封包数据 把多个命令封包内容连续保存为文件或变量, 然后一次性提交以减少网络开销提升性能

addServer() 方法
public XSServer addServer(string $conn)
$conn string 索引服务端连接参数
{return} XSServer
源码: sdk/php/lib/XSIndex.class.php#L33 (显示)
public function addServer($conn)
{
    
$srv = new XSServer($conn$this->xs);
    
self::$_adds[] = $srv;
    return 
$srv;
}

增加一个同步索引服务器

addSynonym() 方法 (自版本 v1.3.0 起可用)
public XSIndex addSynonym(string $raw, string $synonym)
$raw string 需要同义的原词, 英文词汇支持用空格分开多个单词并强制被转换为小写
$synonym string 同义词条, 最小语素, 勿带空格等分隔符
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L283 (显示)
public function addSynonym($raw$synonym)
{
    
$raw strval($raw);
    
$synonym strval($synonym);
    if (
$raw !== '' && $synonym !== '') {
        
$cmd = new XSCommand(XS_CMD_INDEX_SYNONYMSXS_CMD_INDEX_SYNONYMS_ADD0$raw$synonym);
        if (
$this->_bufSize 0) {
            
$this->appendBuffer(strval($cmd));
        } else {
            
$this->execCommand($cmdXS_CMD_OK_RQST_FINISHED);
        }
    }
    return 
$this;
}

添加同义词

beginRebuild() 方法
public XSIndex beginRebuild()
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L391 (显示)
public function beginRebuild()
{
    
$this->execCommand(array('cmd' => XS_CMD_INDEX_REBUILD'arg1' => 0), XS_CMD_OK_DB_REBUILD);
    
$this->_rebuild true;
    return 
$this;
}

开始重建索引 此后所有的索引更新指令将写到临时库, 而不是当前搜索库, 重建完成后调用 endRebuild 实现平滑重建索引, 重建过程仍可搜索旧的索引库, 如直接用 clean 清空数据, 则会导致重建过程搜索到不全的数据

参见

clean() 方法
public XSIndex clean()
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L59 (显示)
public function clean()
{
    
$this->execCommand(XS_CMD_INDEX_CLEAN_DBXS_CMD_OK_DB_CLEAN);
    return 
$this;
}

完全清空索引数据 如果当前数据库处于重建过程中将禁止清空

参见

close() 方法
public void close($ioerr=false)
$ioerr
源码: sdk/php/lib/XSIndex.class.php#L504 (显示)
public function close($ioerr false)
{
    
$this->closeBuffer();
    
parent::close($ioerr);
}

关闭索引服务端连接

closeBuffer() 方法
public XSIndex closeBuffer()
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L378 (显示)
public function closeBuffer()
{
    return 
$this->openBuffer(0);
}

提交所有指令并关闭缓冲区 若未曾打开缓冲区, 调用本方法是无意义的

参见

del() 方法
public XSIndex del(mixed $term, string $field=NULL)
$term mixed 单个主键或指定字段的索引词, 或多个组成的数组, 编码与 xs 默认字符集一致
$field string 索引词所属的字段名称, 默认不指定则为主键字段 (类型为ID)
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L220 (显示)
public function del($term$field null)
{
    
// get field
    
$field $field === null $this->xs->getFieldId() : $this->xs->getField($field);

    
// get commands
    
$cmds = array();
    
$terms is_array($term) ? array_unique($term) : array($term);
    
$terms XS::convert($terms'UTF-8'$this->xs->getDefaultCharset());
    foreach (
$terms as $term) {
        
$cmds[] = new XSCommand(XS_CMD_INDEX_REMOVE0$field->vnostrtolower($term));
    }

    
// combine multi commands into exdata
    
if ($this->_bufSize 0) {
        
$this->appendBuffer(implode(''$cmds));
    } elseif (
count($cmds) == 1) {
        
$this->execCommand($cmds[0], XS_CMD_OK_RQST_FINISHED);
    } else {
        
$cmd = array('cmd' => XS_CMD_INDEX_EXDATA'buf' => implode(''$cmds));
        
$this->execCommand($cmdXS_CMD_OK_RQST_FINISHED);
    }
    return 
$this;
}

删除索引中的数据

$index->del('123');	// 删除主键为 123 的记录
$index->del(array('123', '789', '456')); // 删除主键为 123, 789, 456 的记录
$index->del('abc', 'field'); // 删除字段 field 上带有索引词 abc 的所有记录
$index->del(array('abc', 'def'), 'field'); // 删除字段 field 上带有索引词 abc 或 def 的所有记录

delSynonym() 方法 (自版本 v1.3.0 起可用)
public XSIndex delSynonym(string $raw, string $synonym=NULL)
$raw string 需要同义的原词, 英文词汇支持用空格分开多个单词并强制被转换为小写
$synonym string 要删除的同义词条, 默认 null 表示删除原词下的所有同义词
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L306 (显示)
public function delSynonym($raw$synonym null)
{
    
$raw strval($raw);
    
$synonym $synonym === null '' strval($synonym);
    if (
$raw !== '') {
        
$cmd = new XSCommand(XS_CMD_INDEX_SYNONYMSXS_CMD_INDEX_SYNONYMS_DEL0$raw$synonym);
        if (
$this->_bufSize 0) {
            
$this->appendBuffer(strval($cmd));
        } else {
            
$this->execCommand($cmdXS_CMD_OK_RQST_FINISHED);
        }
    }
    return 
$this;
}

删除某个同义词

endRebuild() 方法
public XSIndex endRebuild()
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L404 (显示)
public function endRebuild()
{
    if (
$this->_rebuild === true) {
        
$this->_rebuild false;
        
$this->execCommand(array('cmd' => XS_CMD_INDEX_REBUILD'arg1' => 1), XS_CMD_OK_DB_REBUILD);
    }
    return 
$this;
}

完成并关闭重建索引 重建完成后调用, 用重建好的索引数据代替旧的索引数据

参见

execCommand() 方法
public void execCommand($cmd, $res_arg=0, $res_cmd=128)
$cmd
$res_arg
$res_cmd
源码: sdk/php/lib/XSIndex.class.php#L44 (显示)
public function execCommand($cmd$res_arg XS_CMD_NONE$res_cmd XS_CMD_OK)
{
    
$res parent::execCommand($cmd$res_arg$res_cmd);
    foreach (
self::$_adds as $srv) {
        
$srv->execCommand($cmd$res_arg$res_cmd);
    }
    return 
$res;
}

执行服务端指令并获取返回值 重写此方法是为了同步到额外增加的多个索引服务端

flushIndex() 方法
public bool flushIndex()
{return} bool 刷新成功返回 true, 失败则返回 false
源码: sdk/php/lib/XSIndex.class.php#L466 (显示)
public function flushIndex()
{
    try {
        
$this->execCommand(XS_CMD_INDEX_COMMITXS_CMD_OK_DB_COMMITED);
    } catch (
XSException $e) {
        if (
$e->getCode() === XS_CMD_ERR_BUSY || $e->getCode() === XS_CMD_ERR_RUNNING) {
            return 
false;
        }
        throw 
$e;
    }
    return 
true;
}

强制刷新服务端的当前库的索引缓存

flushLogging() 方法
public bool flushLogging()
{return} bool 刷新成功返回 true, 失败则返回 false
源码: sdk/php/lib/XSIndex.class.php#L449 (显示)
public function flushLogging()
{
    try {
        
$this->execCommand(XS_CMD_FLUSH_LOGGINGXS_CMD_OK_LOG_FLUSHED);
    } catch (
XSException $e) {
        if (
$e->getCode() === XS_CMD_ERR_BUSY) {
            return 
false;
        }
        throw 
$e;
    }
    return 
true;
}

强制刷新服务端当前项目的搜索日志

getCustomDict() 方法
public string getCustomDict()
{return} string 自定义词库内容
源码: sdk/php/lib/XSIndex.class.php#L484 (显示)
public function getCustomDict()
{
    
$res $this->execCommand(XS_CMD_INDEX_USER_DICTXS_CMD_OK_INFO);
    return 
$res->buf;
}

获取自定义词典内容

getScwsMulti() 方法 (自版本 v1.4.7 起可用)
public int getScwsMulti()
{return} int 返回当前库的分词复合等级
源码: sdk/php/lib/XSIndex.class.php#L347 (显示)
public function getScwsMulti()
{
    
$cmd = array('cmd' => XS_CMD_SEARCH_SCWS_GET'arg1' => XS_CMD_SCWS_GET_MULTI);
    
$res $this->execCommand($cmdXS_CMD_OK_INFO);
    return 
intval($res->buf);
}

获取当前索引库的分词复合等级

参见

openBuffer() 方法
public XSIndex openBuffer(int $size=4)
$size int 缓冲区大小, 单位: MB 默认为 4MB
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L362 (显示)
public function openBuffer($size 4)
{
    if (
$this->_buf !== '') {
        
$this->addExdata($this->_buffalse);
    }
    
$this->_bufSize intval($size) << 20;
    
$this->_buf '';
    return 
$this;
}

开启索引命令提交缓冲区 为优化网络性能, 有必要先将本地提交的 add/update/del 等索引变动指令缓存下来, 当总大小达到参数指定的 size 时或调用 closeBuffer 时再真正提交到服务器 注意: 此举常用于需要大批量更新索引时, 此外重复调用本函数是无必要的

setCustomDict() 方法
public void setCustomDict(string $content)
$content string 新的词典内容
源码: sdk/php/lib/XSIndex.class.php#L495 (显示)
public function setCustomDict($content)
{
    
$cmd = array('cmd' => XS_CMD_INDEX_USER_DICT'arg1' => 1'buf' => $content);
    
$this->execCommand($cmdXS_CMD_OK_DICT_SAVED);
}

设置自定义词典内容

setDb() 方法
public XSIndex setDb(string $name)
$name string 数据库名称
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L439 (显示)
public function setDb($name)
{
    
$this->execCommand(array('cmd' => XS_CMD_INDEX_SET_DB'buf' => $name), XS_CMD_OK_DB_CHANGED);
    return 
$this;
}

更改存放索引数据的目录 默认索引数据保存到服务器上的 db 目录, 通过此方法修改数据目录名

setScwsMulti() 方法 (自版本 v1.4.7 起可用)
public XSIndex setScwsMulti(int $level)
$level int 要设置的分词复合等级
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L331 (显示)
public function setScwsMulti($level)
{
    
$level intval($level);
    if (
$level >= && $level 16) {
        
$cmd = array('cmd' => XS_CMD_SEARCH_SCWS_SET'arg1' => XS_CMD_SCWS_SET_MULTI'arg2' => $level);
        
$this->execCommand($cmd);
    }
    return 
$this;
}

设置当前索引库的分词复合等级 复合等级是 scws 分词粒度控制的一个重要参数, 是长词细分处理依据, 默认为 3, 值范围 0~15 注意: 这个设置仅直对当前索引库有效, 多次调用设置值被覆盖仅最后那次设置有效, 而且仅对设置之后提交的索引数据起作用, 如需对以前的索引数据生效请重建索引.

stopRebuild() 方法 (自版本 v1.3.4 起可用)
public XSIndex stopRebuild()
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L420 (显示)
public function stopRebuild()
{
    try {
        
$this->execCommand(array('cmd' => XS_CMD_INDEX_REBUILD'arg1' => 2), XS_CMD_OK_DB_REBUILD);
        
$this->_rebuild false;
    } catch (
XSException $e) {
        if (
$e->getCode() !== XS_CMD_ERR_WRONGPLACE) {
            throw 
$e;
        }
    }
    return 
$this;
}

中止索引重建 丢弃重建临时库的所有数据, 恢复成当前搜索库, 主要用于偶尔重建意外中止的情况

参见

update() 方法
public XSIndex update(XSDocument $doc, bool $add=false)
$doc XSDocument
$add bool 是否为新增文档, 已有数据中不存在同一主键的其它数据
{return} XSIndex 返回自身对象以支持串接操作
源码: sdk/php/lib/XSIndex.class.php#L85 (显示)
public function update(XSDocument $doc$add false)
{
    
// before submit
    
if ($doc->beforeSubmit($this) === false) {
        return 
$this;
    }

    
// check primary key of document
    
$fid $this->xs->getFieldId();
    
$key $doc->f($fid);
    if (
$key === null || $key === '') {
        throw new 
XSException('Missing value of primary key (FIELD:' $fid ')');
    }

    
// request cmd
    
$cmd = new XSCommand(XS_CMD_INDEX_REQUESTXS_CMD_INDEX_REQUEST_ADD);
    if (
$add !== true) {
        
$cmd->arg1 XS_CMD_INDEX_REQUEST_UPDATE;
        
$cmd->arg2 $fid->vno;
        
$cmd->buf $key;
    }
    
$cmds = array($cmd);

    
// document cmds
    
foreach ($this->xs->getAllFields() as $field/* @var $field XSFieldMeta */ {
        
// value
        
if (($value $doc->f($field)) !== null) {
            
$varg $field->isNumeric() ? XS_CMD_VALUE_FLAG_NUMERIC 0;
            
$value $field->val($value);
            if (!
$field->hasCustomTokenizer()) {
                
// internal tokenizer
                
$wdf $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS 0);
                if (
$field->hasIndexMixed()) {
                    
$cmds[] = new XSCommand(XS_CMD_DOC_INDEX$wdfXSFieldScheme::MIXED_VNO$value);
                }
                if (
$field->hasIndexSelf()) {
                    
$wdf |= $field->isNumeric() ? XS_CMD_INDEX_FLAG_SAVEVALUE;
                    
$cmds[] = new XSCommand(XS_CMD_DOC_INDEX$wdf$field->vno$value);
                }
                
// add value
                
if (!$field->hasIndexSelf() || $field->isNumeric()) {
                    
$cmds[] = new XSCommand(XS_CMD_DOC_VALUE$varg$field->vno$value);
                }
            } else {
                
// add index
                
if ($field->hasIndex()) {
                    
$terms $field->getCustomTokenizer()->getTokens($value$doc);
                    
// self: [bool term, NOT weight, NOT stem, NOT pos]
                    
if ($field->hasIndexSelf()) {
                        
$wdf $field->isBoolIndex() ? : ($field->weight XS_CMD_INDEX_FLAG_CHECKSTEM);
                        foreach (
$terms as $term) {
                            if (
strlen($term) > 200) {
                                continue;
                            }
                            
$term strtolower($term);
                            
$cmds[] = new XSCommand(XS_CMD_DOC_TERM$wdf$field->vno$term);
                        }
                    }
                    
// mixed: [use default tokenizer]
                    
if ($field->hasIndexMixed()) {
                        
$mtext implode(' '$terms);
                        
$cmds[] = new XSCommand(XS_CMD_DOC_INDEX$field->weightXSFieldScheme::MIXED_VNO$mtext);
                    }
                }
                
// add value
                
$cmds[] = new XSCommand(XS_CMD_DOC_VALUE$varg$field->vno$value);
            }
        }
        
// process add terms
        
if (($terms $doc->getAddTerms($field)) !== null) {
            
// ignore weight for bool index
            
$wdf1 $field->isBoolIndex() ? XS_CMD_INDEX_FLAG_CHECKSTEM;
            foreach (
$terms as $term => $wdf) {
                
$term strtolower($term);
                if (
strlen($term) > 200) {
                    continue;
                }
                
$wdf2 $field->isBoolIndex() ? $wdf $field->weight;
                while (
$wdf2 XSFieldMeta::MAX_WDF) {
                    
$cmds[] = new XSCommand(XS_CMD_DOC_TERM$wdf1 XSFieldMeta::MAX_WDF$field->vno$term);
                    
$wdf2 -= XSFieldMeta::MAX_WDF;
                }
                
$cmds[] = new XSCommand(XS_CMD_DOC_TERM$wdf1 $wdf2$field->vno$term);
            }
        }
        
// process add text
        
if (($text $doc->getAddIndex($field)) !== null) {
            if (!
$field->hasCustomTokenizer()) {
                
$wdf $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS 0);
                
$cmds[] = new XSCommand(XS_CMD_DOC_INDEX$wdf$field->vno$text);
            } else {
                
// NOT pos
                
$wdf $field->isBoolIndex() ? : ($field->weight XS_CMD_INDEX_FLAG_CHECKSTEM);
                
$terms $field->getCustomTokenizer()->getTokens($text$doc);
                foreach (
$terms as $term) {
                    if (
strlen($term) > 200) {
                        continue;
                    }
                    
$term strtolower($term);
                    
$cmds[] = new XSCommand(XS_CMD_DOC_TERM$wdf$field->vno$term);
                }
            }
        }
    }

    
// submit cmd
    
$cmds[] = new XSCommand(XS_CMD_INDEX_SUBMIT);

    
// execute cmd
    
if ($this->_bufSize 0) {
        
$this->appendBuffer(implode(''$cmds));
    } else {
        for (
$i 0$i count($cmds) - 1$i++) {
            
$this->execCommand($cmds[$i]);
        }
        
$this->execCommand($cmds[$i], XS_CMD_OK_RQST_FINISHED);
    }

    
// after submit
    
$doc->afterSubmit($this);
    return 
$this;
}

更新索引文档 该方法相当于先根据主键删除已存在的旧文档, 然后添加该文档 如果你能明确认定是新文档, 则建议使用 add

一条评论!

#56 报告
xiaolingzi at 2015-06-29 17:12:23
flushIndex导致数据重复的问题

在调用了add方法后立马调用flushIndex()会出现该document被建立了两条索引了

请到论坛 登录 后刷新本页面!