设为首页 收藏本站
查看: 972|回复: 0

[经验分享] Solr高效利用:Solr实现SQL的查询与统计

[复制链接]

尚未签到

发表于 2016-12-15 11:05:28 | 显示全部楼层 |阅读模式
  Cloudera公司已经推出了基于Hadoop平台的查询统计分析工具Impala,只要熟悉SQL,就可以熟练地使用Impala来执行查询与分析的功能。不过Impala的SQL和关系数据库的SQL还是有一点微妙地不同的。
下面,我们设计一个表,通过该表中的数据,来将SQL查询与统计的语句,使用Solr查询的方式来与SQL查询对应。这个翻译的过程,是非常有趣的,你可以看到Solr一些很不错的功能。
用来示例的表结构设计,如图所示:
<ignore_js_op> DSC0000.png


下面,我们通过给出一些SQL查询统计语句,然后对应翻译成Solr查询语句,然后对比结果
查询对比
条件组合查询
SQL查询语句:

  • SELECT log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type
  • FROM v_i_event
  • WHERE prov_id = 1 AND net_type = 1 AND area_id = 10304 AND time_type = 1 AND time_id >= 20130801 AND time_id <= 20130815
  • ORDER BY log_id LIMIT 10;

复制代码

查询结果,如图所示:
<ignore_js_op> DSC0001.png

Solr查询URL:

  •         http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type&fq=prov_id:1 AND net_type:1 AND area_id:10304 AND time_type:1 AND time_id:[20130801 TO 20130815]&sort=log_id asc&start=0&rows=10

复制代码

查询结果,如下所示:


  • <response>
  • <lst name="responseHeader">
  •         <int name="status">0</int>
  •         <int name="QTime">4</int>
  •     </lst>
  • <result name="response" numFound="77" start="0">
  •         <doc>
  • <int name="log_id">6827</int>
  • <long name="start_time">1375072117</long>
  • <long name="end_time">1375081683</long>
  •             <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">10304</int>
  • <int name="idt_id">11002</int>
  •             <int name="cnt">0</int>
  • <int name="net_type">1</int>
  • </doc>
  • <doc>
  •             <int name="log_id">6827</int>
  •             <long name="start_time">1375072117</long>
  •             <long name="end_time">1375081683</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">10304</int>
  •             <int name="idt_id">11000</int>
  • <int name="cnt">0</int>
  •             <int name="net_type">1</int>
  • </doc>
  •         <doc>
  •             <int name="log_id">6851</int>
  •             <long name="start_time">1375142158</long>
  •             <long name="end_time">1375146391</long>
  •             <int name="prov_id">1</int>
  •             <int name="city_id">103</int>
  • <int name="area_id">10304</int>
  • <int name="idt_id">14001</int>
  •             <int name="cnt">5</int>
  • <int name="net_type">1</int>
  • </doc>
  • <doc>
  • <int name="log_id">6851</int>
  • <long name="start_time">1375142158</long>
  •             <long name="end_time">1375146391</long>
  •             <int name="prov_id">1</int>
  •             <int name="city_id">103</int>
  •             <int name="area_id">10304</int>
  • <int name="idt_id">11002</int>
  • <int name="cnt">23</int>
  • <int name="net_type">1</int>
  • </doc>
  •         <doc>
  •             <int name="log_id">6851</int>
  • <long name="start_time">1375142158</long>
  •             <long name="end_time">1375146391</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">10304</int>
  • <int name="idt_id">10200</int>
  • <int name="cnt">55</int>
  •             <int name="net_type">1</int>
  • </doc>
  • <doc>
  •             <int name="log_id">6851</int>
  • <long name="start_time">1375142158</long>
  • <long name="end_time">1375146391</long>
  • <int name="prov_id">1</int>
  •             <int name="city_id">103</int>
  •             <int name="area_id">10304</int>
  •             <int name="idt_id">14000</int>
  • <int name="cnt">4</int>

复制代码

对比上面结果,除了根据idt_id排序方式不同以外(Impala是升序,Solr是降序),其他是相同的。
单个字段分组统计
SQL查询语句:

  • SELECT prov_id, SUM(cnt) AS sum_cnt, AVG(cnt) AS avg_cnt, MAX(cnt) AS max_cnt, MIN(cnt) AS min_cnt, COUNT(cnt) AS count_cnt
  • FROM v_i_event
  • GROUP BY prov_id;

复制代码

查询结果,如图所示:
<ignore_js_op> DSC0002.png


Solr查询URL:

  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&stats=true&stats.field=cnt&rows=0&indent=true

复制代码

  
查询结果,如下所示:


  • <response>
  •     <lst name="responseHeader">
  •         <int name="status">0</int>
  • <int name="QTime">2</int>
  • </lst>
  •     <result name="response" numFound="4088" start="0"></result>
  •     <lst name="stats">
  • <lst name="stats_fields">
  • <lst name="cnt">
  • <double name="min">0.0</double>
  • <double name="max">1258.0</double>
  •                 <long name="count">4088</long>
  •                 <long name="missing">0</long>
  • <double name="sum">32587.0</double>
  • <double name="sumOfSquares">9170559.0</double>
  • <double name="mean">7.971379647749511</double>
  •                 <double name="stddev">46.69344567709268</double>
  •                 <lst name="facets" />
  •             </lst>
  • </lst>
  • </lst>
  • </response>

复制代码
对比查询结果,Solr提供了更多的统计项,如标准差(stddev)等,与SQL查询结果是一致的。
IN条件查询
SQL查询语句:
[cde lang="sql"]
SELECT log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_typ
FROM v_i_event
WHERE prov_id = 1 AND net_type = 1 ANDcity_id IN(106,103) AND idt_id IN(12011,5004,6051,6056,8002) AND time_type = 1AND time_id >= 20130801 AND time_id <= 20130815
ORDER BY log_id, start_time DESC LIMIT 10;
[/code]
查询结果,如图所示:
<ignore_js_op> DSC0003.png
  
Solr查询URL:

  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id, cnt,net_type&fq=prov_id:1 AND net_type:1 AND (city_id:106 OR city_id:103) AND (idt_id:12011 OR idt_id:5004 OR idt_id:6051 OR idt_id:6056 OR idt_id:8002) AND time_type:1 AND time_id:[20130801 TO 20130815]&sort=log_id asc ,start_time desc&start=0&rows=10

复制代码
  


  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id, cnt ,net_type&fq=prov_id:1&fq=net_type:1&fq=(city_id:106 OR city_id:103)&fq=(idt_id:12011 OR idt_id:5004 OR idt_id:6051 OR idt_id:6056 OR idt_id:8002)&fq=time_type:1&fq=time_id:[20130801 TO 20130815]&sort=log_id asc,start_time desc&start=0&rows=10

复制代码
  
查询结果,如下所示:


  • <response>
  •     <lst name="responseHeader">
  • <int name="status">0</int>
  • <int name="QTime">6</int>
  • </lst>
  • <result name="response" numFound="63" start="0">
  • <doc>
  •             <int name="log_id">6553</int>
  • <long name="start_time">1374054184</long>
  • <long name="end_time">1374054254</long>
  •             <int name="prov_id">1</int>
  •             <int name="city_id">103</int>
  •             <int name="area_id">10307</int>
  • <int name="idt_id">12011</int>
  • <int name="cnt">0</int>
  • <int name="net_type">1</int>
  • </doc>
  • <doc>
  • <int name="log_id">6553</int>
  • <long name="start_time">1374054184</long>
  •             <long name="end_time">1374054254</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">10307</int>
  • <int name="idt_id">5004</int>
  • <int name="cnt">2</int>
  •             <int name="net_type">1</int>
  • </doc>
  • <doc>
  •             <int name="log_id">6555</int>
  • <long name="start_time">1374055060</long>
  • <long name="end_time">1374055158</long>
  •             <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  •             <int name="area_id">70104</int>
  • <int name="idt_id">5004</int>
  • <int name="cnt">3</int>
  • <int name="net_type">1</int>

复制代码
  

对比查询结果,是一致的。
开区间范围条件查询
SQL查询语句:
SELECTlog_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type
FROM v_i_event
WHERE net_type = 1 AND idt_idIN(12011,5004,6051,6056,8002) AND time_type = 1 AND start_time >= 1373598465AND end_time < 1374055254
ORDER BY log_id, start_time, idt_id DESCLIMIT 30;
查询结果,如图所示:
<ignore_js_op> DSC0004.png
  

Solr查询URL:

  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type&fq=net_type:1 AND (idt_id:12011 OR idt_id:5004 OR idt_id:6051 OR idt_id:6056 OR idt_id:8002) AND time_type:1 AND start_time:[1373598465 TO 1374055254]&fq =-start_time:1374055254&sort=log_id asc,start_time asc,idt_id desc&start=0&rows=30

复制代码



  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type&fq=net_type:1 AND (idt_id:12011 OR idt_id:5004 OR idt_id:6051 OR idt_id:6056 OR idt_id:8002) AND time_type:1 AND start_time:[1373598465 TO 1374055254] AND -start_time:1374055254&sort=log_id asc,start_time asc,idt_id desc&start=0&rows=30

复制代码



  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&fl=log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type&fq=net_type:1&fq=idt_id:12011 OR idt_id:5004 OR idt_id:6051 OR idt_id:6056 OR idt_id:8002&fq =time_type:1&fq=start_time:[1373598465 TO 1374055254]&fq =-start_time:1374055254&sort=log_id asc,start_time asc,idt_id desc&start=0&rows=30

复制代码

查询结果,如下所示:


  • <response>
  • <lst name="responseHeader">
  • <int name="status">0</int>
  • <int name="QTime">5</int>
  • </lst>
  • <result name="response" numFound="4" start="0">
  • <doc>
  •             <int name="log_id">6553</int>
  • <long name="start_time">1374054184</long>
  • <long name="end_time">1374054254</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">10307</int>
  • <int name="idt_id">12011</int>
  • <int name="cnt">0</int>
  • <int name="net_type">1</int>
  • </doc>
  • <doc>
  • <int name="log_id">6553</int>
  • <long name="start_time">1374054184</long>
  •             <long name="end_time">1374054254</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  •             <int name="area_id">10307</int>
  • <int name="cnt">2</int>
  • <int name="net_type">1</int>
  • </doc>
  •         <doc>
  • <int name="log_id">6555</int>
  • <long name="start_time">1374055060</long>
  • <long name="end_time">1374055158</long>
  • <int name="prov_id">1</int>
  • <int name="city_id">103</int>
  • <int name="area_id">70104</int>
  • <int name="idt_id">12011</int>
  •             <int name="cnt">0</int>
  • <int name="net_type">1</int>
  • </doc>
  • <doc>
  •             <int name="log_id">6555</int>
  • <long name="start_time">1374055060</long>
  • <long name="end_time">1374055158</long>
  • <int name="prov_id">1</int>
  •             <int name="city_id">103</int>
  • <int name="area_id">70104</int>
  • <int name="idt_id">5004</int>
  • <int name="cnt">3</int>
  • <int name="net_type">1</int>
  • </doc>
  • </result>
  • </response>

复制代码

多个字段分组统计(只支持count函数)
SQL查询语句:
SELECT city_id, area_id, COUNT(cnt) AScount_cnt
FROM v_i_event
WHERE prov_id = 1 AND net_type = 1
GROUP BY city_id, area_id;
查询结果,如图所示:
<ignore_js_op> DSC0005.png
Solr查询URL:

  • http://slave1:8888/solr-cloud/i_event/select?q=*:*&facet=true&facet.pivot=city_id,area_id&fq=prov_id:1 AND net_type:1&rows=0&indent=true

复制代码

对比上面结果,Solr查询结果,需要从上面的各组中进行合并,得到最终的统计结果,结果和SQL结果是一致的。
多个字段分组统计(支持count、sum、max、min等函数)
一次对多个字段进行独立分组统计,Solr可以很好的支持。这相当于执行两个带有GROUP BY子句的SQL,这两个GROUP BY分别只对一个字段进行汇总统计。
SQL查询语句:

  • SELECT city_id, area_id, COUNT(cnt) AS count_cnt
  • FROM v_i_event
  • WHERE prov_id = 1 AND net_type = 1
  • GROUP BY city_id;

  • SELECT city_id, area_id, COUNT(cnt) AS count_cnt
  • FROM v_i_event
  • WHERE prov_id = 1 AND net_type = 1
  • GROUP BY area_id;

复制代码

查询结果,不再显示。

Solr查询URL:

  • >http://slave1:8888/solr-cloud/i_event/select?q=*:*&stats=true&stats.field=cnt&f.cnt.stats.facet=city_id&&f.cnt.stats.facet=area_id&fq=prov_id:1 AND net_type:1&rows=0&indent=true

复制代码

查询结果,如下所示:

  • <response>
  •     <lst name="responseHeader">
  •         <int name="status">0</int>
  •         <int name="QTime">72</int>
  •     </lst>
  •     <result name="response" numFound="1171" start="0"></result>
  •     <lst name="facet_counts">
  •         <lst name="facet_queries" />
  •         <lst name="facet_fields" />
  •         <lst name="facet_dates" />
  •         <lst name="facet_ranges" />
  •         <lst name="facet_pivot">
  •             <arr name="city_id,area_id">
  •                 <lst>
  •                     <str name="field">city_id</str>
  •                     <int name="value">103</int>
  •                     <int name="count">678</int>
  •                     <arr name="pivot">
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10307</int>
  •                             <int name="count">298</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10315</int>
  •                             <int name="count">120</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10317</int>
  •                             <int name="count">86</int>
  •                         </lst>
  •                         <lst>
  • <str name="field">area_id</str>
  •                             <int name="value">10304</int>
  •                             <int name="count">67</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10310</int>
  •                             <int name="count">49</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">70104</int>
  •                             <int name="count">48</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10308</int>
  •                             <int name="count">6</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">0</int>
  •                             <int name="count">2</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10311</int>
  •                             <int name="count">2</int>
  •                         </lst>
  •                     </arr>
  •                 </lst>
  •                 <lst>
  •                     <str name="field">city_id</str>
  •                     <int name="value">0</int>
  •                     <int name="count">463</int>
  •                     <arr name="pivot">
  • <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">0</int>
  •                             <int name="count">395</int>
  •                         </lst>
  •                         <lst>
  •                             <str name="field">area_id</str>
  •                             <int name="value">10307</int>
  •                             <int name="count">68</int>

复制代码

对比上面结果,Solr查询结果,需要从上面的各组中进行合并,得到最终的统计结果,结果和SQL结果是一致的。
  

多个字段联合分组统计(支持count、sum、max、min等函数)
SQL查询语句:
SELECT city_id, area_id, SUM(cnt) ASsum_cnt, AVG(cnt) AS avg_cnt, MAX(cnt) AS max_cnt, MIN(cnt) AS min_cnt,COUNT(cnt) AS count_cnt
FROM v_i_event
WHERE prov_id = 1 AND net_type = 1
GROUP BY city_id, area_id;
查询结果,如图所示:
<ignore_js_op> DSC0006.png
Solr目前不能简单的支持这种查询,如果想要满足这种查询统计,需要在schema的设计上,将一个字段设置为多 值,然后通过多个值进行分组统计。如果应用中查询统计分析的模式比较固定,预先知道哪些字段会用于联合分组统计,完全可以在设计的时候,考虑设置多值字段 来满足这种需求。
  
感兴趣的读者,还可以看看这里:基于Solr DIH实现MySQL表数据全量索引和增量索引

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-314709-1-1.html 上篇帖子: Solr 5.x的搭建(Solr自带的Jetty Server)与mmseg4j中文分词 下篇帖子: 转:Nutch和Solr的集成方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表