Solr高效利用:Solr实现SQL的查询与统计

1.如何高效使用Solr查询功能 ?
2.单个字段分组统计如何实现?
3.IN条件查询有几种方式?
4.多个字段分组统计是否只支持count?




Cloudera公司已经推出了基于Hadoop平台的查询统计分析工具Impala,只要熟悉SQL,就可以熟练地使用Impala来执行查询与分析的功能。不过Impala的SQL和关系数据库的SQL还是有一点微妙地不同的。
下面,我们设计一个表,通过该表中的数据,来将SQL查询与统计的语句,使用Solr查询的方式来与SQL查询对应。这个翻译的过程,是非常有趣的,你可以看到Solr一些很不错的功能。
用来示例的表结构设计,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第1张图片 


下面,我们通过给出一些SQL查询统计语句,然后对应翻译成Solr查询语句,然后对比结果
查询对比
条件组合查询
SQL查询语句:
  1. SELECT log_id,start_time,end_time,prov_id,city_id,area_id,idt_id,cnt,net_type
  2. FROM v_i_event
  3. WHERE prov_id = 1 AND net_type = 1 AND area_id = 10304 AND time_type = 1 AND time_id >= 20130801 AND time_id <= 20130815
  4. ORDER BY log_id LIMIT 10;
复制代码

查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第2张图片 

Solr查询URL:
  1.         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
复制代码

查询结果,如下所示:



  1.         0
  2.         4
  3.    

  4.         
  5. 6827
  6. 1375072117
  7. 1375081683
  8.             1
  9. 103
  10. 10304
  11. 11002
  12.             0
  13. 1


  14.             6827
  15.             1375072117
  16.             1375081683
  17. 1
  18. 103
  19. 10304
  20.             11000
  21. 0
  22.             1

  23.         
  24.             6851
  25.             1375142158
  26.             1375146391
  27.             1
  28.             103
  29. 10304
  30. 14001
  31.             5
  32. 1


  33. 6851
  34. 1375142158
  35.             1375146391
  36.             1
  37.             103
  38.             10304
  39. 11002
  40. 23
  41. 1

  42.         
  43.             6851
  44. 1375142158
  45.             1375146391
  46. 1
  47. 103
  48. 10304
  49. 10200
  50. 55
  51.             1


  52.             6851
  53. 1375142158
  54. 1375146391
  55. 1
  56.             103
  57.             10304
  58.             14000
  59. 4
复制代码

对比上面结果,除了根据idt_id排序方式不同以外(Impala是升序,Solr是降序),其他是相同的。

单个字段分组统计

SQL查询语句:
  1. 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
  2. FROM v_i_event
  3. GROUP BY prov_id;
复制代码

查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第3张图片 


Solr查询URL:
  1. http://slave1:8888/solr-cloud/i_event/select?q=*:*&stats=true&stats.field=cnt&rows=0&indent=true
复制代码


查询结果,如下所示:


  1.    
  2.         0
  3. 2

  4.    
  5.    


  6. 0.0
  7. 1258.0
  8.                 4088
  9.                 0
  10. 32587.0
  11. 9170559.0
  12. 7.971379647749511
  13.                 46.69344567709268
  14.                
  15.             


复制代码

对比查询结果,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]
查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第4张图片 

Solr查询URL:
  1. 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
复制代码


  1. 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
复制代码

查询结果,如下所示:


  1.    
  2. 0
  3. 6



  4.             6553
  5. 1374054184
  6. 1374054254
  7.             1
  8.             103
  9.             10307
  10. 12011
  11. 0
  12. 1


  13. 6553
  14. 1374054184
  15.             1374054254
  16. 1
  17. 103
  18. 10307
  19. 5004
  20. 2
  21.             1


  22.             6555
  23. 1374055060
  24. 1374055158
  25.             1
  26. 103
  27.             70104
  28. 5004
  29. 3
  30. 1
复制代码


对比查询结果,是一致的。

开区间范围条件查询
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;
查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第5张图片 


Solr查询URL:
  1. 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
复制代码

  1. 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
复制代码

  1. 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
复制代码

查询结果,如下所示:



  1. 0
  2. 5



  3.             6553
  4. 1374054184
  5. 1374054254
  6. 1
  7. 103
  8. 10307
  9. 12011
  10. 0
  11. 1


  12. 6553
  13. 1374054184
  14.             1374054254
  15. 1
  16. 103
  17.             10307
  18. 2
  19. 1

  20.         
  21. 6555
  22. 1374055060
  23. 1374055158
  24. 1
  25. 103
  26. 70104
  27. 12011
  28.             0
  29. 1


  30.             6555
  31. 1374055060
  32. 1374055158
  33. 1
  34.             103
  35. 70104
  36. 5004
  37. 3
  38. 1



复制代码


多个字段分组统计(只支持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;
查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第6张图片 

Solr查询URL:
  1. 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查询语句:
  1. SELECT city_id, area_id, COUNT(cnt) AS count_cnt
  2. FROM v_i_event
  3. WHERE prov_id = 1 AND net_type = 1
  4. GROUP BY city_id;

  5. SELECT city_id, area_id, COUNT(cnt) AS count_cnt
  6. FROM v_i_event
  7. WHERE prov_id = 1 AND net_type = 1
  8. GROUP BY area_id;
复制代码

查询结果,不再显示。

Solr查询URL:
  1. >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
复制代码

查询结果,如下所示:

  1.    
  2.         0
  3.         72
  4.    
  5.    
  6.    
  7.         
  8.         
  9.         
  10.         
  11.         
  12.             
  13.                
  14.                     city_id
  15.                     103
  16.                     678
  17.                     
  18.                         
  19.                             area_id
  20.                             10307
  21.                             298
  22.                         
  23.                         
  24.                             area_id
  25.                             10315
  26.                             120
  27.                         
  28.                         
  29.                             area_id
  30.                             10317
  31.                             86
  32.                         
  33.                         
  34. area_id
  35.                             10304
  36.                             67
  37.                         
  38.                         
  39.                             area_id
  40.                             10310
  41.                             49
  42.                         
  43.                         
  44.                             area_id
  45.                             70104
  46.                             48
  47.                         
  48.                         
  49.                             area_id
  50.                             10308
  51.                             6
  52.                         
  53.                         
  54.                             area_id
  55.                             0
  56.                             2
  57.                         
  58.                         
  59.                             area_id
  60.                             10311
  61.                             2
  62.                         
  63.                     
  64.                
  65.                
  66.                     city_id
  67.                     0
  68.                     463
  69.                     

  70.                             area_id
  71.                             0
  72.                             395
  73.                         
  74.                         
  75.                             area_id
  76.                             10307
  77.                             68
复制代码

对比上面结果,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;

查询结果,如图所示:
Solr高效利用:Solr实现SQL的查询与统计_第7张图片 

Solr目前不能简单的支持这种查询,如果想要满足这种查询统计,需要在schema的设计上,将一个字段设置为多值,然后通过多个值进行分组统计。如果应用中查询统计分析的模式比较固定,预先知道哪些字段会用于联合分组统计,完全可以在设计的时候,考虑设置多值字段来满足这种需求。

感兴趣的读者,还可以看看这里: 基于Solr DIH实现MySQL表数据全量索引和增量索引

你可能感兴趣的:(其他)