【问题标题】:Parsing search queries in Java在 Java 中解析搜索查询
【发布时间】:2010-09-06 01:05:09
【问题描述】:

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

我找到了两个解决方案:

  1. Lucene:强大的基于 Java 的搜索引擎,包含一个查询解析器,但它不是很可配置,我可以找到一种方法来轻松破解/调整它以创建 SQL 查询。
  2. ANTLR:资深的文本词法分析器。用于构建从编译器到摩天大楼的任何东西。 ANTLR 是高度可配置的,但从现在开始接触代码的每个人都必须学习一门新语言......

还有其他想法吗?

【问题讨论】:

    标签: java search


    【解决方案1】:

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

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

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

    【讨论】:

    • 非常有趣。好像没有映射和 XML 的 IBatis
    【解决方案2】:

    你到底有什么想法?我使用 Lucene 进行文本搜索,但它的优势在于构建索引并搜索该索引而不是完全访问数据库。

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

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

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

    【讨论】:

      【解决方案3】:

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

      例如:“哈利波特”变成了

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

      而“publisher:Nature* pages > 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);
      }
      

      其余的你可以想象。您可以随意嵌套 And 表达式。

      【讨论】:

        【解决方案4】:

        很大程度上取决于您必须解析的查询类型以及数据库中数据的结构。我将假设您没有尝试在数据库(即整个数据库中的搜索引擎)中进行全文搜索,因为正如大多数信息检索人员会告诉您的那样,这样做的性能很糟糕。倒排索引无疑是最好的方法。

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

        【讨论】:

          【解决方案5】:

          您认为我不是在寻找全文搜索是正确的。 该信息类似于图书信息的此架构: 名称:字符串,发布者:字符串,num_pages int,发布日期:日期...

          搜索查询是这样的:

          1. 哈利波特(搜索任何名字中同时包含哈利和波特的书籍)
          2. publisher:Nature* 页>100(来自以 Nature 开头的出版商的书籍,超过 100 本书)
          3. (“新年”或圣诞节)和礼物(你明白了......)
          4. physics and publish>1/1/2008(新物理书籍)

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              字符串[]数组;

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

              【讨论】:

              • 这并不能真正回答问题。
              猜你喜欢
              • 1970-01-01
              • 2021-06-01
              • 1970-01-01
              • 2023-02-15
              • 2014-06-21
              • 1970-01-01
              • 2011-05-30
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多