zoukankan      html  css  js  c++  java
  • SolrCloud6.1.0之SQL查询测试

     


    Solr发展飞快,现在最新的版本已经6.1.0了,下面来回顾下Solr6.x之后的一些新的特点: 


    (1)并行SQL特性支持,编译成Streaming 表达式,可以在solrcloud集群中,并行执行 
    (2)SolrCloud的Collection被抽象成关系型数据库表,现在不仅仅可以支持强大的全文检索,还通过SQL支持像数据库一样的BI分析 
    (3)在SQL的where语句中,全面支持强大的Lucene/Solr语法 
    (4)一些聚合操作例如Group会自动优化成并行操作,通过使用Streaming表达式来以Map-Reduce的方式运行 
    (5)在(4)中运行的聚合操作,还可以以原生的JSON Facet 方式,来优化提升性能 
    (6)SQL特性目前仅支持SolrCloud集群方式,单机方式并不支持 



    有关SolrCloud的集群搭建,在这里散仙就不详细说了,有兴趣的朋友,可以参考我前面的文章 
    http://qindongliang.iteye.com/blog/2275990,搭建好的集群如下: 





    实际上像Solr或者ElasticSearch能支持SQL,这并不奇怪,因为他们底层基本上都提供了SQL能支持的大部分功能接口,比如,排序,过滤 
    分组,聚合等一些操作,能支持SQL,但不意味着能取代关系型数据库,恰恰相反,NoSQL是作为SQL的有力补充,怎么样组合搭配使用,能把业务 
    场景优化的更好,或者能解决某类问题,才是引入这些框架的初衷。 

    前面说到,Solr在api层面已经有各种功能的接口,缺的就是一个SQL语法解析器,以及如何与最新的Java8的对接? 所以在Solr6.x里面,引入两个 
    最重要的东东就是: 

    (1)引入了Facebook开源的大数据SQL检索框架Presto的SQL Parser 
    (2)使用Java8的Streaming Api写的Streaming Expressions (流式表达式),支持类似shell的管道的计算方式,可以对数据流进行各种复杂操作例如各种join, 
    也可以进行图谱查询 


    使用Solrj通过JDBC查询Solr,目前只能查,暂不支持更新,修改,删除等操作 
    依赖jar包: 
    $SOLR_HOME/dist/solrj-libs  所有的jar 
    $SOLR_HOME/dist/solr-solrj-<version>.jar   solr-solrj.jar 
    如果是maven项目: 

    Java代码  收藏代码
    1. <!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj -->  
    2. <dependency>  
    3.     <groupId>org.apache.solr</groupId>  
    4.     <artifactId>solr-solrj</artifactId>  
    5.     <version>6.1.0</version>  
    6. </dependency>  



    下面来看一段Solrj通过JDBC查询示例: 

    Java代码  收藏代码
    1. Connection con=null;  
    2.     Statement stmt=null;  
    3.     ResultSet rs=null;  
    4.     try{  
    5.         String collection="sql_search";    
    6.         String aggregationMode="facet";// facet or map_reduce  
    7.         //注意solr//:后面跟的是zk集群地址,如果有chroot path还需要加上  
    8.         con=DriverManager.getConnection("jdbc:solr://192.168.1.184:2181/solr6?collection="+collection+"&aggregationMode="+aggregationMode+"&numWorkers=2");  
    9.         //检索,排序,topN  
    10.         String sql1="select dtime  from big_search order by dtime desc limit 4 ";  
    11.         //多级分组,排序1  
    12.         String sql2="select t1,t2,t3 , count(*)  from big_search group by t1,t2 ,t3 order by count(*) desc limit 3  ";  
    13.         //分组,过滤,排序2          
    14.         String sql21="select t1, count(*)  from big_search group by t1 having count(*) > 2 order by count(*) desc    ";  
    15.         //去重  
    16.         String sql221="select distinct t3 from sql_search limit 2  ";  
    17.         //全文检索查询  
    18.         String sql15="select rowkey from big_search  where title='(你好 苏州)' limit 4  ";  
    19.         //聚合函数  支持max,min,avg,sum,count  
    20.         String sql4="select count(*) from big_search  limit 2 ";  
    21.         //提取字段  
    22.         String sql3="select t1,t2 from big_search ";  
    23.         stmt = con.createStatement();//编译sql  
    24.         rs = stmt.executeQuery(sql21);//执行sql  
    25.         ResultSetMetaData metaData = rs.getMetaData(); //获取字段名元数据  
    26.         String line_space=" "; //格式化打印  
    27.         for(int i=1;i<=metaData.getColumnCount();i++){  
    28.             System.out.print(metaData.getColumnName(i)+line_space);//打印表头  
    29.         }  
    30.         System.out.println();  
    31.         while(rs.next()) {//循环从游标提取数据  
    32.             for(int i=1;i<=metaData.getColumnCount();i++){//遍历列头  
    33.                 System.out.print(rs.getString(metaData.getColumnName(i))+line_space);//格式化打印字段内容  
    34.             }  
    35.             System.out.println();  
    36.         }  
    37.         } finally {  
    38.             if(rs!=null){  
    39.         rs.close();  
    40.             }  
    41.             if(stmt!=null){  
    42.         stmt.close();  
    43.             }  
    44.             if(con!=null){  
    45.         con.close();  
    46.             }  
    47.         }  
    48.   
    49.     System.out.println("====end====");  




    下面来看一段使用流式表达式查询的操作,无须任何依赖,在Solr的Admin界面就能操作; 
    图中的代码的是查询solrcloud中每个shard一条数据,然后总共返回3条数据,最后对3条数据,排序,取top1 








    总结: 

    (1)关于如何集成中文分词IK或者Ansj 

    单机版的solr,如果是IK,需要在 
    solrserversolr-webappwebappWEB-INF目录下,新建一个classes目录,将其词库文件全部放进去
    然后将IK的jar包,放入solrserversolr-webappwebappWEB-INFlib下。 

    如果是Ansj,则需要将Ansj相关的jar包放入solrserversolr-webappwebappWEB-INFlib下, 
    然后将Ansj的library的目录,放在solrserver中。 

    在SolrCloud集群模式中,是需要把某个collection下的conf下的所有文件,上传到zookeeper上的,所有的shard都会 
    从zk上加载所需的文件,包括一些词库的配置,这个时候,放在本地磁盘上的词库,是不会被识别的,所以你需要把上传的词库 
    文件一起上传到zk上,然后配置合理的路径即可,任何文件的更新,都需要reload整个collection才能更新(solr6之前是需要relaod所有的shard), 
    否则,发生的改动不会被识别。 


    (2)理解map_reduce  和 facet两种聚合模式 

    A: map_reduce  模式,支持任意多字段的聚合查询,不受限制,但性能稍低 
    测试环境5个shard+3个副本 
    测试数据,必须大于6(shard+1)条数据,否则会报错 

    可测 group+distict 





    执行流程如下: 

     



    B:facet   模式,使用Solr原生的Json Facet Api 操作,受一定索引的限制,但性能较高 
    只要求有shard,有数据,即可测试,利用solr原生的Facet api进行聚合 





    (3)理解DocValue对SQL查询的影响 
    大部分情况下在Solr中的SQL查询,是需要加上limit关键词的,如果你不加,要么你就会发现,你的查询可能会莫名其妙的报错 
    这个时候问题的原因大部分是跟DocValue有关的, Solr6要求,所有不加的limit查询的字段,必须全部是DocValue激活的 
    字段,如果任何一个不是,那么查询肯定报错,如果你加了limit关键词,要么可以不受这个限制影响。 

    至于为什么必须要激活DocValue字段才能进行all字段提取查询,主要目的还是为了性能,想了解DocValue可以 
    参考散仙之前的文章:http://qindongliang.iteye.com/blog/2297280 



    (4) Solr6支持客户端工具(像MySQL的NaviCat)查询链接: 

    A:DbVisualizer  (C/S客户端GUI) 
    B:SQuirreL SQL (C/S客户端GUI) 
    C:Apache Zeppelin  (B/S web端) 
    大部分都需要配置添加有关的solr的jdbc的jar包,具体安装方式参考文末链接 

    (5)除了JDBC方式支持SQL查询,http方式也是可以的: 

    Shell代码  收藏代码
    1. [search@h1 ~]$ cat sql.sh   
    2. ## 聚合模式 map_reduce  
    3. #curl --data-urlencode 'stmt=SELECT t1, count(*) FROM sql_search GROUP BY t1 ORDER BY count(*) desc LIMIT 10'  http://192.168.1.120:8983/solr/sql_search/sql?aggregationMode=map_reduce  
    4. ## 聚合模式 facet  
    5. curl --data-urlencode 'stmt=SELECT t1, count(*) FROM sql_search GROUP BY t1 ORDER BY count(*) desc LIMIT 10'  http://192.168.1.120:8983/solr/sql_search/sql?aggregationMode=facet  
    6. [search@h1 ~]$ sh sql.sh   
    7. {"result-set":{"docs":[  
    8. {"count(*)":4,"t1":"01"},  
    9. {"count(*)":2,"t1":"02"},  
    10. {"count(*)":2,"t1":"03"},  
    11. {"count(*)":2,"t1":"04"},  
    12. {"count(*)":2,"t1":"05"},  
    13. {"EOF":true,"RESPONSE_TIME":84}]}}  




    官网文档: 
    https://cwiki.apache.org/confluence/display/solr/Streaming+Expressions 
    https://cwiki.apache.org/confluence/display/solr/Parallel+SQL+Interface#ParallelSQLInterface-SQLClientsandDatabaseVisualizationTools 



    有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 
    技术债不能欠,健康债更不能欠, 求道之路,与君同行。 

  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/qindongliang/p/5662972.html
Copyright © 2011-2022 走看看