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

简介: 假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。

尽管lucenesolr如此的频繁、如此的普遍被使用。仍然有许多人、需要开发者所见即所得的方式,将查询用起来。一方面为了迎合传统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 对应nameid|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

目录
相关文章
|
4月前
|
SQL Oracle 关系型数据库
SQL 通配符:用于模糊搜索和匹配的 SQL 关键技巧
通配符字符用于替代字符串中的一个或多个字符。通配符字符与LIKE运算符一起使用。LIKE运算符用于在WHERE子句中搜索列中的指定模式。
55 0
|
SQL XML Oracle
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
372 0
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
|
1月前
|
Oracle Java 关系型数据库
【问题】Cause: java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK
【问题】Cause: java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK
|
4月前
|
SQL 存储
百度搜索:蓝易云【高级SQL语句】
这些是SQL中一些常见的高级语句示例,它们可以帮助你处理更复杂的查询和数据操作需求。请根据具体情况选择适当的语句,并参考相关的SQL文档和教程来进一步了解和学习。
36 0
|
4月前
|
SQL Java 数据库连接
【Java调试】通过SqlSessionFactory类对象获取mapper文件内的动态SQL在执行时的完整SQL及参数(2种使用方法+测试Demo及结果)
【Java调试】通过SqlSessionFactory类对象获取mapper文件内的动态SQL在执行时的完整SQL及参数(2种使用方法+测试Demo及结果)
55 0
|
4月前
|
Oracle Java 关系型数据库
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
28 0
|
4月前
|
SQL 数据库连接 数据库
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
VB.NET 中使用SqlConnection类连接到Microsoft SQL Server数据库的详细步骤
97 0
|
4月前
|
SQL Java 数据库连接
util包和sql包里的Date类区别,该用哪一个?
util包和sql包里的Date类区别,该用哪一个?
29 0
|
4月前
|
SQL 数据库 开发者
百度搜索:蓝易云【SQL高级之慢查询日志?】
慢查询日志是数据库性能优化中一个重要的工具,通过记录执行时间较长的查询语句,帮助识别和解决数据库中的性能问题。它提供了有价值的信息,帮助开发者和管理员优化查询和提升数据库的性能。
55 6
|
4月前
|
SQL XML Java
mybatis SQL类
mybatis SQL类
45 1