您的位置:首页 > 数据库

HubbleDotNet开源全文搜索数据库项目--查询方法汇总 ——>eaglet

2010-09-13 15:47 591 查看
HubbleDotNet的查询语法为类SQL语句,本文以示例的形式讲述HubbleDotNet的各种查询方法。随着功能不断的增加,查询方法还会不断补充。

本文给出如下查询方法的示例:

对单个字段按或方式匹配

对单个字段按与方式匹配

对单个字段按部分与,部分或方式匹配

对多个字段匹配并分页

和Untokenized类型字段组合查询

按多字段排序

在搜索结果中查找

搜索结果中不包含

对单个字段GROUPBY

同时输出多个字段的Groupby统计结果

对多字段组合进行Groupby

GroupByLimit设置

同构表联合查询

异构表联合查询

采用UnionSelect对海量数据分割为小表后联合查询

基本查询

对单个字段按或方式匹配

搜索标题中包含“北京”“大学”两个关键字的所有记录,并按照得分的大小排倒序

SQL语句:

selecttop10*fromCNewswheretitlematch'北京^5000^0大学^5000^2'orderbyscoredesc


单词分量后面跟的参数^5000^0含义如下

第一个参数表示这个单词分量的权值,这里为5000。

第二个参数表示这个单词分量在输入的被搜索的句子中的其实位置,如这里“北京”的位置为0,大学的起始位置为2.

top10表示输出前10条匹配的记录

Score为得分,这个是一个动态字段。

结果:





对单个字段按与方式匹配

搜索标题包含abcnewstocut这几个关键字中所有关键字的记录,并按匹配度排序

SQL语句:

selecttop10Id,Title,ScorefromEnglishNewswheretitlecontains'abc^5000^0news^5000^3to^5000^7cut^5000^9'

orderbyscoredesc


采用Contains搜索,可以进行精确匹配,这里我们发现采用Contains搜索出来的数据要比Match少很多。因为只有

同时包含abcnewstocut这四个单词的记录才会被输出出来。

结果:





对单个字段按部分与,部分或方式匹配

上面的例子,由于to这个词太常见,我们希望匹配同时包含abcnewscut这三个单词的记录,并且记录中如果包含to,

则得分比不包含to的得分高。这种搜索方法已经很解决google或baidu的搜索方法了,google中如果输入关键字中包含停用词,

对非停用词采用与的方式匹配,对停用词采用或的方式匹配,但如果记录中包含要匹配的停用词,则得分比不包含的要高。

SQL语句:

selecttop10Id,Title,ScorefromEnglishNewswheretitlecontains'abc^5000^0news^5000^3to^5000^7^1cut^5000^9'orderbyscoredesc



这里我们看出,多出了一条记录,这条记录排在第三位,和前两条记录比起来,这条记录没有to这个单词。

to这个单词分量后面跟的参数说明:

to^5000^7^1

前两个参数和其他单词的意思一样,一个为权重,一个为位置。

第三个参数为标志字段,1表示可以为或。

结果:





对多个字段匹配并分页

搜索标题或内容中包含“北京”“大学”两个关键字的所有记录,并按照得分的大小排倒序

SQL语句:

selectbetween0to9*fromCNewswheretitle^2match'北京^5000^0大学^5000^2'or
contentmatch'北京^5000^0大学^5000^2'orderbyscoredesc


这里title字段后跟了一个参数2,这个参数表示title字段的权值为2,也就是说通过这种方法对字段设置权值。

between0to9表示输出0到9范围内的记录,这种方法可以用于分页显示。

结果:






和Untokenized类型字段组合查询

搜索标题中包含“北京”“大学”两个关键字的,并且时间大于2007年1月1日小于2007年8月16日的所有记录,并按照时间排倒序

SQL语句:

selecttop10*fromCNewswheretitle^2match'北京^5000^0大学^5000^2'andtime>'2007-1-1'and
time<'2007-8-16'orderbytimedesc



结果:





按多字段排序

搜索标题中包含“北京”“大学”两个关键字的,并且时间大于2007年1月1日小于2007年8月16日的所有记录,并按照时间和得分同时排倒序

即先按时间排序,时间相同的记录,得分高的排前面。

SQL语句:

selecttop10*fromCNewswheretitle^2match'北京^5000^0大学^5000^2'
orderbytimedesc,scoredesc


结果:





在搜索结果中查找

在match'abc^5000^0news^5000^3to^5000^7cut^5000^9'的结果中再查找包含Staff这个词的记录

SQL语句:

selecttop10Id,Title,ScorefromEnglishNewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

andtitlecontains'Staff'orderbyscoredesc


结果:





搜索结果中不包含

在match'abc^5000^0news^5000^3to^5000^7cut^5000^9'的结果中再查找不含包含Staff这个词的记录

SQL语句:

selecttop10Id,Title,ScorefromEnglishNewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

andtitlenotcontains'Staff'orderbyscoredesc


结果:





GROUPBY功能

对单个字段GROUPBY

搜索标题包含abcnewstocut这几个关键字中任意一个关键字的记录,并按匹配度排序,同时按GroupId字段做统计,

输出记录最多的10个groupid

SQL语句:


[GroupBy('Count','*','GroupId',10)]
selecttop10Id,Title,ScorefromEnglishNewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

orderbyscoredesc



第一个参数表示采用什么统计函数,目前只支持Count,以后还会增加Sum,AVG等等。

第二个参数为统计函数参数,填*,相当于count(*)

第三个参数为要统计的字段名,GroupBy字段必须为untokenized类型索引字段且不能是字符串类型。
最后一个参数10是可选参数,表示返回前10个最多的分组统计结果,如果不填,返回所有分组统计结果。

这个语句执行后,会输出2个DataTable第一个是select语句的结果集,第二个是groupby的结果集。也就是说在全文搜索时同时进行分组统计,

这样使用起来更方便,而且速度更快。

GroupBy部分的伪SQL语句是

selecttop10GroupId,count(*)ascountfromenglishnewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

groupbyGroupIdorderbycountdesc


结果:





同时输出多个字段的Groupby统计结果

很多应用,特别是电子商务类应用,查询时需要输出多个分类的统计结果,HubbleDotNet可以在一次查询中同时输出多个分类的统计结果,极大的方便了这方面的应用。而且HubbleDotNet的GroupBy功能是在底层进行统计的,比Lucene的统计需要在结果输出后再通过程序进行过滤统计要简单快速很多。

[GroupBy('Count','*','GroupId',10)]
[GroupBy('Count','*','SiteId',10)]
selecttop10Id,GroupId,SiteId,Title,ScorefromEnglishNewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

orderbyscoredesc






这个语句同时输出针对GroupId和SiteId两个字段的统计结果。


对多字段组合进行Groupby

本例对GroupId和SiteId的组合进行Groupby

[GroupBy('Count','*','GroupId,SiteId',10)]
selecttop10Id,GroupId,SiteId,Title,ScorefromEnglishNewswheretitlematch'abc^5000^0news^5000^3to^5000^7cut^5000^9'

orderbyscoredesc

上述语句可以针对多个字段进行分组统计。要注意的是多字段GroupBy时,多个字段的占用字节数总和不可以超过8字节。及最多2个int类型,

或者8个tinyint类型。





GroupByLimit设置

HubbleDotNet的表属性中有一个GroupByLimit设置,这个设置的意思是在做Groupby时只针对前GroupByLimit条记录进行统计,如果查询的返回结果集的记录行数大于这个数值,则统计结果为约数,不是实数,在界面上应显示为类似(2500+)这样的形式。这个设置的目的是提高分组统计的效率,默认为40000,如果觉得这个值比较小,可以调大。





多表联合查询功能

HubbleDotNet提供类似SQLUnion这样的多表联合查询的功能,用于分布式查询,异构表联合查询。

同构表联合查询

本例为两个相同结构的表联合查询

SQL语句:

[UnionSelect]
selecttop10title,content,scorefromEnglishNewswherecontentmatch'news'orderbyscoredesc;
selecttop10title,content,scorefromNewswherecontentmatch'news'orderbyscoredesc;


这个语句对EnglishNews和News这个两个表联合查询匹配News这个词的记录,按匹配相关度排序,并返回前10条记录。

这里要注意的是:

联合查询的多条SQL语句必须有top或者between关键字来指明实际输出多少结果集。每条语句指定的结果集数量必须相当,

比如这里都指定为10。这里实际返回的结果集数量小于等于10,而不是小于等于20.

每条SQL语句的返回字段名必须相同

必须有orderby语句,指明按什么字段进行排序

联合查询的SQL语句必须以分号“;”分割

联合查询的SQL语句数量没有限制

查询后返回两个DataTable,第一个表是联合查询的结果集,第二个表是联合查询中各个语句实际匹配的记录数。这里News表匹配了9条记录

而EnglishNews表匹配3896条记录。

结果:





异构表联合查询

很多网站的应用中,要全文查询的表不止一种,比如一个网站有博客,有新闻,这些表的字段名都不相同,如果我们希望通过一个统一的入口来查询所有博客和新闻的全文,过去的方法是把博客和新闻的数据整合到一个全文索引结构中,然后进行查询,这样做是对资源的严重浪费。HubbleDotNet通过UnionSelect功能,可以对这种异构表联合查询的需求进行支持,你可以通过SQL语句任意动态组合不同的异构数据表进行查询,而不需要重新建立索引。

SQL语句:

[UnionSelect]
selecttop10title,abstractascontent,scorefromAllIndexwhereabstractcontains'北京^5000^0大学^5000^2'orderbyscoredesc;
selecttop10title,content,scorefromNewswherecontentcontains'北京^5000^0大学^5000^2'orderbyscoredesc;


这个语句对AllIndex和News这个两个表联合查询匹配北京大学这个词的记录,按匹配相关度排序,并返回前10条记录。

由于AllIndex和News表结构不同,AllIndex中没有content字段,而是abstract字段,所以在这个联合查询语句中,我们将abstract字段通过as关键字改名为content字段输出,这样两个查询语句返回的字段名就相同了,就可以实现异构表的联合查询了。

结果:





采用UnionSelect对海量数据分割为小表后联合查询

对于5000万行以上的海量数据,可以通过分割为多个小表然后联合查询的方式来提高查询效率,由于UnionSelect查询时,多条SQL语句是并行执行的,在多核计算机上,并行查询可以大大提高查询速度,海量数据分割后查询的速度也会比单个大表的查询速度要快。另外分割成小表还有一个好处是提高了索引和优化的效率,如果一个大表的索引文件大小为600G,那么每次优化都会生成一个600G这么大的索引文件,其耗时是巨大的。但如果分割为10个60G的表,则优化只要生成60G大小的索引文件,耗时要小10倍。而且很多应用是只有增量和删除,这种情况下很多历史表一旦生成就不需要再重新索引了,比如我们每天生成一个索引表,那么只要每天对当天的索引表索引就可以了,不需要将当天的索引和历史索引合并,这样索引的效率就大大提高了。

HubbleDotNet海量数据测试报告这篇文章中的海量数据就是分割为8个小表联合查询来做的。

对于2000万行一下的数据,如果索引文件不是特别大,可以单表索引,联合查询对性能的提升有限。

返回Hubble.net技术详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: