用Java解析搜索查询

时间:2008-08-17 19:21:26

标签: java search

我一直在尝试找到一种简单的方法来解析搜索查询并将其转换为我的数据库的SQL查询。

我找到了两个解决方案:

  1. Lucene :强大的基于Java的搜索引擎,包含一个查询解析器,但它不是很容易配置,我可以找到一种方法来轻松破解/调整它来创建SQL查询
  2. ANTLR :经验丰富的文本词法分析器。用于构建从编译器到摩天大楼的任何东西。 ANTLR具有高度可配置性,但从现在开始每个人都需要学习一种新语言......
  3. 还有其他想法吗?

7 个答案:

答案 0 :(得分:3)

SQL-ORM是一个非常轻量级的Java库,它包含在Java中构建(动态)SQL查询作为对象图的能力

恕我直言,这是一种比通常的字符串连接方法更好的构建动态SQL查询的技术。

免责声明:我对此项目做了一些非常次要贡献

答案 1 :(得分:1)

您可以尝试使用javacc(Java Compiler Compiler)之类的东西来实现解析器,或者只是通过强力手动解析字符串。每次遇到表达式时,都将其表示为对象。然后,您只需将表达式树转换为where子句。

例如:“哈利波特”成为

new AndExp(new FieldContainsExp("NAME", "Harry"), new FieldContainsExp("NAME", "Potter")

“发布商:自然*页面> 100”变为

new AndExp(new FieldContainsExp("PUBLISHER", "Nature"), FieldGreaterThan("PAGES", 100))

然后,一旦你有了这些,很容易将它们变成SQL:

FieldContainsExp.toSQL(StringBuffer sql, Collection<Object> args) {
  sql.append(fieldName);
  sql.append(" like ");
  sql.append("'%?%'");
  args.add(value);
}

AndExp.toSQL(StringBuffer sql, Collection<Object> args) {
    exp1.toSQL(sql, args);
    sql.append(" AND ");
    exp2.toSQL(sql, args);
}

你可以想象其余的。您可以根据需要深入嵌套和表达式。

答案 2 :(得分:1)

你究竟想到了什么?我已经使用Lucene进行文本搜索,但它擅长的是构建索引并搜索而不是来访问数据库。

我最近建立了一个系统,我通过将所有列(用空格分隔)连接到一个字段中,然后将其弹出到Lucene中,然后在单独的列中添加主键,在Lucene中索引表。 Lucene进行所有搜索并返回主键列表,我用它来提取一组填充的结果并显示给用户。

在我看来,将搜索查询转换为SQL语句会有点混乱。

此外,这里是a great beginning tutorial explaining the basic structure of Lucene

答案 3 :(得分:0)

很大程度上取决于您需要解析的查询类型以及数据库中数据的结构。我将假设您不是在尝试在数据库中进行全文搜索(即整个数据库中的搜索引擎),因为正如大多数信息检索人员会告诉您的那样,其性能非常糟糕。倒置索引肯定是最好的方法。

告诉我们更多关于实际问题的信息:用户将要输入什么,他们期望输出什么,以及数据模型是什么样的。设计一个没有这些信息的搜索解决方案,你将得到远远不是最佳结果。

答案 4 :(得分:0)

你认为我不是在寻找全文搜索是正确的。 该信息看起来像书籍信息的这个架构: 名称:字符串,发布者:字符串,num_pages int,publish_date:date ...

搜索查询属于以下类别:

  1. 哈利波特(搜索任何名字上都有哈利和波特的书)
  2. 发布商:自然* 页面&gt; 100(来自出版商的图书以Nature开头,超过100本图书)
  3. (“新年”或圣诞节)和礼物(你得到的照片......)
  4. 物理和发布&gt; 1/1/2008 (新物理书籍)

答案 5 :(得分:0)

尝试组合ORM工具(如openJPA)和Compass(OSEM框架)。 它会自动为通过ORM工具完成的更新编制索引,并为您提供Lucene搜索功能。之后,您可以从DB中检索对象。 它胜过任何基于SQL的搜索解决方案。

答案 6 :(得分:-2)

String [] array;

int checkWord(String searchWord)
{
    for(int i = 0; i < array.length; i++)
    {
        if(searchWord.equals(array[i]))
            return i;
    }
    return 0;

}