Sql Support within Solr-类Sql的solr搜索实现(1)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 尽管lucene、solr如此的频繁、如此的普遍被使用。仍然有许多人、需要开发者所见即所得的方式,将查询用起来。一方面为了迎合传统sql用户的习惯,另一方面提升通用搜索产品的可用性,也丰富solr的功能接口。有必要实现 类sql的 solr查询实现。   社区总是无比的强大,总是只要你能想到的

尽管lucene、solr如此的频繁、如此的普遍被使用。仍然有许多人、需要开发者所见即所得的方式,将查询用起来。一方面为了迎合传统sql用户的习惯,另一方面提升通用搜索产品的可用性,也丰富solr的功能接口。有必要实现

类sql的 solr查询实现。

 

社区总是无比的强大,总是只要你能想到的一定有人想到,只要你想到的一定有人已经尝试在实现,甚至已经有实现的初级版本,这个开头就给予了屌丝很好的指引。类sql的开源项目
solrflux就是这么一个开源项目。目前看,貌似没多少人关注这个。从注释和用例看,作者是日本友好人士。http://code.google.com/p/solrflux/

 

1. solrflux 用例体验

public class TestDemo {
  public static void main(String[] args) throws
IOException
    
{
        
//ConsoleReader conReader = new ConsoleReader();
     
String filedemo="testSql2Solr.txt"; // 改为从文件读取sql 语法
        
BufferedReader fileReader = new BufferedReader( new
InputStreamReader(new FileInputStream(filedemo)));
        

        
EvalContext ctx = new EvalContext();

        
StringBuilder builder = new StringBuilder();
        
CharSequenceReader reader = new CharSequenceReader(builder);
        

        
final String NORMAL_PROMPT = "SQL>";
        
final String CONTD_PROMPT = "... ";

        
String prompt = NORMAL_PROMPT;
        

        
String targetUrl="http://localhost:8080/terminator-search/search4****-0";

        
String name ="conn"; //这个name 对应testSql2Solr.txt 中的 信息,然后关联到
targetUrl     

        
UseStatement use = new UseStatement();
        
use.setUrl( targetUrl );
        
use.setName( name );
        
try {
             
use.execute(ctx);
        
} catch (Exception e) {
             
e.printStackTrace();
        
}
        

        

        
while (true)
{       

            
String line = fileReader.readLine();
            
//System.out.println("--"+line);
            
if ( line == null ) {
            
 System.out.println("line is null so exit");
                
break;
            
}
           
// String line ="SELECT * FROM conn WHERE id="104614938"";
            

            
builder.append(line + "n");
            
reader.reset();
            
try {
                
if ( tryEvaluate( reader, ctx ) ) {
                    
prompt = NORMAL_PROMPT;
                
} else {
                    
prompt = CONTD_PROMPT;
                    
continue;
                
}
            
} catch (Exception e) {
                
e.printStackTrace();
                
prompt = NORMAL_PROMPT;
            
}finally{
            
 
            
}
            
builder.setLength(0);
            
builder.trimToSize();
        
}
        
fileReader.close();
    
}
 
    

    
private static boolean tryEvaluate(Reader reader, EvalContext
ctx)
    
throws SyntaxException, EvalException, IOException
    
{     

      //String
expr= null;
    
 //ANTLRStringStream  in = new
ANTLRStringStream(expr);  
        
ANTLRReaderStream stream = new ANTLRReaderStream( reader
);        

        
RecognizerSharedState state = new RecognizerSharedState();
        
SolrqlLexer lexer = new SolrqlLexer(stream, state);//词法分析器
        
CommonTokenStream tokenStream = new
CommonTokenStream(lexer);//获取lexer构造的记号流
        
SolrqlParser parser = new SolrqlParser(tokenStream);//语法分析器
        

        
try {
            
stmt_list_return ret = parser.stmt_list();
            
if (ret != null) {
                
evaluate((CommonTree)ret.getTree(), ctx);
            
}
        
} catch (MismatchedTokenException e) {
            
if (e.getUnexpectedType() == SolrqlParser.EOF) {
                
// immature input. continue.
                
return false;
            
} else {
                
throw new SyntaxException(
                        
lexer.getErrorMessage(e, SolrqlParser.tokenNames), e);
            
}
        
} catch (RecognitionException e) {
            
throw new SyntaxException(
                    
lexer.getErrorMessage(e, SolrqlParser.tokenNames), e);
        
}
        

        
return true;
    
}
    

    

    
private static void evaluate(CommonTree t, EvalContext ctx)
    
throws EvalException, SyntaxException
    
{
        
printTree(t, 0);
        

        
List statements = new StatementListBuilder().build(t);
        

        
for (Statement stmt: statements) {
            
Object ret = stmt.execute(ctx);
            

            
if ( ret == null ) {
                
System.out.println("OK.");
                
continue;
            
}
            

            
if ( ret instanceof UpdateResponse ) {
                
printUpdateResponse((UpdateResponse)ret);
            
} else if ( ret instanceof SelectStatement.Result ) {
                
printSelectResult((SelectStatement.Result)ret);
            
} else {
                
System.out.println("Result: " + ret.toString());
            
}
        
}
    
}
    

    
private static void printSelectResult(SelectStatement.Result
res)
    
{
        
int i=1;
        
for (SolrDocument doc: res.getDocuments()) {
            
System.out.print(Integer.toString(i) + ": ");
            
int j=0;
            
for (Map.Entry e: doc.entrySet()) {
                
if (j > 0) {
                    
System.out.print(", ");
                
}
                
System.out.print(e.getKey() + "=" + e.getValue().toString());
                
++j;
            
}
            
System.out.println();
            
++i;
        
}
        

        
System.out.println();
        
System.out.println("Query=" + res.getQuery());
        
System.out.println(
                
"Found " + res.getResponse().getResults().getNumFound() +
                
" documents, Offset=" +
res.getResponse().getResults().getStart()
                
);
        
System.out.println(
                
"Status=" + res.getResponse().getStatus() +
                
", Elapsed Time=" + res.getResponse().getElapsedTime()
                
);
    
}
    

    
private static void printUpdateResponse(UpdateResponse res)
    
{
        
System.out.println(
                
"Status=" + res.getStatus() +
                
", Elapsed Time=" + res.getElapsedTime()
                
);
    
}

    
private static void printTree(Tree t, int indent)
    
{
        
if (t != null) {
            
StringBuffer sb = new StringBuffer(indent);
            
for (int i = 0; i < indent; ++i) {
                
sb =
sb.append("   
");
            
}

            
if (!t.isNil()) {
                
System.out.println(sb.toString() + t.toString());
                
++indent;
            
}

            
for (int i = 0; i < t.getChildCount(); ++i) {
                
printTree(t.getChild(i), indent);
            
}
        
}
    
}
}

-------------------------testSql2Solr.txt--------------

SELECT * FROM conn ;
SELECT * FROM conn WHERE id="1581";
SELECT * FROM conn WHERE id!="1581";
SELECT id,nick FROM conn WHERE 0<2000;
SELECT * FROM conn NWHERE "se_isv_type:4 AND isv_id:[* TO
2000]";
SELECT SUBSTRING(description, 0, 3) AS first_three_letters From
conn WHERE description="sdf";
SELECT * FROM conn WHERE id!="1581" ORDER BY score DESC;
SELECT * FROM conn WHERE id!="1581" ORDER BY score DESC limit 10
offset 10;
SELECT SUBSTRING(description, 0, 4) AS first_fouth_letters From
conn WHERE description="sdfs";

---------------------------------------------------------------

说明,其中conn 对应name,id|nick|isv_id| description
 对应schema中的域

limit ~ rows

offset ~ start

solrflux 文法-语法-抽象语法树参考 grammar/Solral.g,

可以实现学习下 antlr 基本原理

http://www.ibm.com/developerworks/cn/java/j-lo-antlr/index.html?ca=drs-

然后 下载 antlrwork 对句法、文法等编辑、测试


http://openjdk.java.net/projects/compiler-grammar/antlrworks/index.html

相关文章
|
7月前
|
SQL Oracle 关系型数据库
SQL 通配符:用于模糊搜索和匹配的 SQL 关键技巧
通配符字符用于替代字符串中的一个或多个字符。通配符字符与LIKE运算符一起使用。LIKE运算符用于在WHERE子句中搜索列中的指定模式。
102 0
|
4月前
|
SQL 数据处理 数据库
SQL正则表达式应用:文本数据处理的强大工具——深入探讨数据验证、模式搜索、字符替换等核心功能及性能优化和兼容性问题
【8月更文挑战第31天】SQL正则表达式是数据库管理和应用开发中处理文本数据的强大工具,支持数据验证、模式搜索和字符替换等功能。本文通过问答形式介绍了其基本概念、使用方法及注意事项,帮助读者掌握这一重要技能,提升文本数据处理效率。尽管功能强大,但在不同数据库系统中可能存在兼容性问题,需谨慎使用以优化性能。
64 0
|
6月前
|
SQL 监控 安全
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
|
5月前
|
SQL
常用工具类---SQL工具,HTTP工具
SQL工具,HTTP工具,两个实用小工具~~~
|
6月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版操作报错合集之在执行SQL语句时遇到了类找不到,该怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
147 0
|
7月前
|
Oracle Java 关系型数据库
【问题】Cause: java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK
【问题】Cause: java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK
|
7月前
|
SQL 存储
百度搜索:蓝易云【高级SQL语句】
这些是SQL中一些常见的高级语句示例,它们可以帮助你处理更复杂的查询和数据操作需求。请根据具体情况选择适当的语句,并参考相关的SQL文档和教程来进一步了解和学习。
69 0
|
7月前
|
SQL Java 数据库连接
【Java调试】通过SqlSessionFactory类对象获取mapper文件内的动态SQL在执行时的完整SQL及参数(2种使用方法+测试Demo及结果)
【Java调试】通过SqlSessionFactory类对象获取mapper文件内的动态SQL在执行时的完整SQL及参数(2种使用方法+测试Demo及结果)
236 0
|
7月前
|
Oracle Java 关系型数据库
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
125 0
|
7月前
|
SQL 数据库连接 数据库
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
316 0

热门文章

最新文章