LUCENE索引结构是以2叉树为基础的B树倒排结构,这决定了索引数据时要维护2叉树为基础的B树倒排结构,例如查找并增量,将耗费一定的时间消耗,其时间复杂度为O(LOGN),而sphinx是以HASH哈希树为基础的倒排结构,其时间复杂度为O(1),所以随着数据的增多,LUCENE索引树的维护将超过sphinx索引树的维护。导致sphinx索引速度是LUCENE索引速度的10倍这么大的差距。
附:Lucene 倒排序索引原理
Lucene 倒排序索引原理
Lucene是apache软件基金会[4] jakarta项目组的一个子项目,是一个高性能的java全文检索框架。lucene索引结构中最核心的部分是倒排序索引。
用一个例子描述一下倒排序。
假设有两篇文章:
文章1的内容是:共和国。
文章2的内容是:中国。
1、Lucene在建立索引前先通过分词器找出文章中的关键词。我们采用一元分词举例。那么文章1的关键词是[共][和][国],文章二的关键词是[中][国]。
2、倒排序索引
通过分词器找出的对应关系是文章到关键词映射,这样处理后的结果不利于检索,几乎是全扫描。lucene再用倒排序建立索引,把这种关系转换成关键词到文章的映射,并对关键词做字符串排序。当然lucene还补充了关键词在文章中出现的频度和位置等信息,这里不做描述。到排序后的结果见下表:
关键词
文章号
共
国
1,2
和
中
简单的说lucene倒排序就是把分词词元映射到文章位置并对这些记录按分词词元做字符串排序。
对于这样的存储结构,lucene采用了二元搜索算法来做检索。这也是lucene高效的原因之一。
对二元搜索算法做一下简单介绍:即二分查找或折半查找算法,对于有n个元素的数组来说,二元搜索算法进行最多1+log2(n)次比较. 即有2的n次方个元素,最多比较n+1次。那么1024*1024*1024个元素,也就比较31次而已。
违禁词分词过滤思路
违禁词分词思路:建立违禁词词典,词元是一个违禁词(包括特殊符号,并且不考虑正向和逆向最大匹配)。那么用违禁词分词器分词后的倒排序就是把违禁词映射到文章位置并对这些记录按违禁词做字符串排序。
例如:共和国是违禁词
对文章1和文章2的倒排序索引就是:
关键词
文章号
共和国
明显地,索引记录数等于违禁词数。这样,通过一次建倒排序索引的过程就直接找出目标记录,可大大提高计算效率。
此方法用于执行数据库命令
public Object Execute(string[] prams, string cmdType)
此方法可以执行四种常用的增删改查的sql数据库命令
调用示例:
string[] prams = {"select * from Table1 where id=@id", "id", id }; //格式为:{sql命令,参数键,参数值} (其中参数键,参数值可以为空)
string cmdType = "select";
Dataset ds = Execute(prams, cmdType);
prams:string数组,格式:{sql命令,参数键,参数值} (其中参数键,参数值可以为空)
cmdType: 包括四种值"insert","delete","update","select"
返回值为一个Object对象,所以使用此方法的返回值时需要进行强制转换
public Object Execute(string[] prams, string cmdType) { this.Open(); //一条语句无参数 if (cmdType == "select") { //select语句 返回DataSet if (prams.Length == 1) { string cmd = prams[0]; DataSet ds = new DataSet(); SqlDataAdapter dap = new SqlDataAdapter(cmd, con); dap.Fill(ds); this.Close(); return ds; } else { //sql带参数命令 string cmd = prams[0]; //获取临界数组下表 int paramMid = (prams.Length - 1) / 2; string[] PramsKey = new string[100]; string[] PramsValue = new string[100]; //获取参数键 for (int i = 1,j = 0; i <= paramMid; i++,j++) { PramsKey[j] = prams[i]; } for (int i = paramMid + 1,j=0; i <= prams.Length-1; i++,j++) { PramsValue[j] = prams[i]; } SqlCommand sqlCmd = con.CreateCommand(); sqlCmd.CommandText = cmd; for (int i = 0; i < paramMid; i++) { sqlCmd.Parameters.Add(new SqlParameter(PramsKey[i], PramsValue[i])); } SqlDataAdapter dap = new SqlDataAdapter(sqlCmd); DataSet ds = new DataSet(); dap.Fill(ds); this.Close(); return ds; } } //sql插入命令,返回影响的行数 //sql更新命令,返回影响的行数 //sql删除命令,返回影响的行数 if (cmdType == "insert" || cmdType == "update" || cmdType == "delete") { //sql命令无参数 if (prams.Length == 1) { SqlCommand cmd = con.CreateCommand(); cmd.CommandText = prams[0]; int num = cmd.ExecuteNonQuery(); this.Close(); return num; } //sql命令有参数 else { //sql带参数命令 SqlCommand cmd = con.CreateCommand(); cmd.CommandText = prams[0]; //数组下表临界值 int paramMid = (prams.Length - 1) / 2; string[] paramKey = new string[100]; string[] paramValue = new string[100]; //获取键 for (int i = 1, j = 0; i <= paramMid; i++, j++) { paramKey[j] = prams[i]; } //cmd.Parameters.Clear(); //获取值 for (int i = paramMid + 1, j = 0; i <= prams.Length - 1; i++, j++) { paramValue[j] = prams[i]; } //添加参数 for (int i = 0; i < paramMid; i++) { cmd.Parameters.Add(new SqlParameter(paramKey[i], paramValue[i])); } int num = cmd.ExecuteNonQuery(); //cmd.Parameters.Clear(); this.Close(); return num; } } this.Close(); return null; }
Open-flash-chart及代理类设计介绍
目录
1介绍open-flash-chart. 1
2最简单的测试用例... 1
3代理类... 2
3.1 为何设计代理类... 2
3.1 open-flash-chart 模型图... 4
3.2 代理之后模型图... 4
3.3 代理之后的好处... 4
4 实际例子... 5
4.1 折线图... 5
4.2 面积图... 6
4.3 比较折线图前台页和面积图前台页... 8
5 不足与更新... 8
6 附件代码测试方法... 8
1介绍open-flash-chart
Open-flash-chart是一款用 open-flash-chart.swf 作为统计显示端,支持http数据源的统计工具
http://teethgrinder.co.uk/open-flash-chart/
我们下面的内容都是针对1.9.6版本来讲.
所有代码文件,及内容格式均为utf-8
2最简单的测试用例Open-flash-chart 的使用上分为两个部分
1) 前端展示页
2) 后端数据页
下面是一个简单的折线图的例子
1) 前端展示页代码 test1.php
<?php
include_once 'ofc-library/open_flash_chart_object.php';
open_flash_chart_object( 500, 250, 'http://'. $_SERVER['SERVER_NAME'] .'/1.9.6/data-1.php', false );
?>
2) 后端数据页代码
<?php
include_once( 'ofc-library/open-flash-chart.php' );
$xarr=array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' );
$yarr = array('1','5','7','8','4','6','9','10','12','11','13','33');
$ymax = 40;
$g = new graph();
$g->title( '最简单的例子 ', '{font-size: 26px;}' );
$g->set_x_labels($xarr );
$g->set_data( $yarr );
$g->set_y_max( $ymax );
echo $g->render();
?>
3) 效果
因为使用open-free-chart每次使用来做工作,可能需要做2个事情。
1) 做一个前端展示页
2) 做一个后台数据源
因此,希望有一个代理类,能完成如下工作
希望有一个完整的能够在前端显示页代理操作的类
class_myline
该类功能如下
(1)设置标题
(2)设置数据,数据格式形式如下为
$lm_array =array
(
"qiyi"=>array(
"00:00"=>20.64
"00:05"=>21.64
"00:10"=>22.64
"00:15"=>53.64
),
"cnc"=>array(
"00:00"=>30.64
"00:05"=>31.64
"00:10"=>32.64
"00:15"=>13.64
),
"letv"=>array(
"00:00"=>40.64
"00:05"=>41.64
"00:10"=>42.64
"00:15"=>43.64
"00:20"=>44.64
"00:21"=>25.64
)
);
(3)直接输出上面的图
3.1 open-flash-chart 模型图3.2 代理之后模型图
3.3 代理之后的好处
1)数据整理和展示都在show page.
后台页只作为一个类似图形驱动的存在,和数据不再关联
2)数据整理的方式被归纳为一致,不在和展示图形的样子有关系,可以方便的将图形驱动页由折线图更改为面积图
4 实际例子 4.1 折线图
1)前台页
<?php
include_once 'ofc-library/open_flash_chart_object.php';
include_once 'class_myline.php';
session_start();
$lm_array =array
(
"qiyi"=>array(
"00:00"=> 20.64,
"00:05"=> 21.64,
"00:10"=> 22.64,
"00:15"=> 53.64,
"00:20"=> 44.64,
"00:21"=> 25.64
),
);
$ml=new class_myline();
$ml->set_title("运营商流量比较图");
$ml->set_xtitle("时间");
$ml->set_ytitle("带宽");
$ml->set_data($lm_array);
var_dump($ml);
$char_data = serialize($ml);
$_SESSION['char_data']=$char_data;
open_flash_chart_object( 500, 250, 'http://'. $_SERVER['SERVER_NAME'] .'/