【问题标题】:How to implement a search in multiple fields based on condition(s)如何根据条件在多个字段中实现搜索
【发布时间】:2015-04-16 00:50:17
【问题描述】:

我正在尝试实现休眠全文搜索。用户可以选择哪些字段与搜索相关或不相关。这是通过 JSF 中的六个(我的示例)布尔复选框来完成的。

六个布尔值表示 2^6 种可能的组合。我需要映射所有这些条件。

例子:

boolean a;
boolean b;
boolean c;
boolean d;
boolean e;
boolean f;

if(a){
// do a search with a 
}

..

if(a && b){
// do a search with a and b only
}

..

if(a && b && c){
// do a search with a and b and c only
}

在每个 IF 语句中,都应该调用一个方法。

基于我的案例的特别示例:

用户想要搜索具有姓和/或名字的用户。

org.apache.lucene.search.Query luceneQuery = qb.keyword()
                    .onFields("user.surname", "user.givenname")
                    .matching(searchstring).createQuery();

条件:

QueryBuilder qb = fullTextEntityManager.getSearchFactory()
            .buildQueryBuilder().forEntity(BeitragVO.class).get();

if(user){
org.apache.lucene.search.Query luceneQuery = qb.keyword()
                        .onFields("user.surname", "user.givenname")
                        .matching(searchstring).createQuery();
}

if(company){
org.apache.lucene.search.Query luceneQuery = qb.keyword()
                        .onField("company.name")
                        .matching(searchstring).createQuery();
}

   if(student && company){

    // How can I add all relevant fields(givenname, surname, and name of     
    company) to the query?
    }

有没有办法比 64 IF 做得更好?

【问题讨论】:

  • // do a search with a and b and c only 实际上是什么样子的?
  • 您应该将“使用a 进行搜索”封装到某种A 对象中。然后使用SetSearchCriterion 或类似的东西。
  • 我也更新了我的问题。我真的错过了这一点,谢谢@AnthonyGrist
  • Alexander,我想这是我的错误,试图修改我的问题以向您展示如何通过尝试编写代码来实现您的目标。所以,我用所有这些修改删除了我的答案,并用我原来的答案替换了它,只有一个修改将我的答案与 lucene 联系起来。这个答案保持原样。您可以等待,看看其他人是否发布了一个答案,该答案为您提供了您需要的实际可运行代码。
  • 没问题,迈克。我还是猜,你没明白我的意思。但是没关系!我真的很高兴,你已经尽力了!

标签: java hibernate if-statement conditional-statements hibernate-criteria


【解决方案1】:

您可以这样编写代码:

String search = "";

if(a){
    search += ...
}

..

if(b){
    search += ...
}

..

if(c){
    search += ...
}

只需通过每个复选框自己的选择添加任何 SQL 查询(条件)代码,然后运行它

【讨论】:

  • 这确实很有帮助,但很遗憾不是我的意思,抱歉。还是投赞成票。
【解决方案2】:

Hibernate 搜索最好使用条件查询来完成。 (查找它们。)在条件查询中,您逐个构建查询。所以,你最终会得到这样的东西:

create criteria query
add non-changing criteria query parts (like where to search, what to retrieve)
if( a ) add criteria query term for a
if( b ) add criteria query term for b
...
execute query

编辑:同样的原则也适用于 Lucene 查询。

【讨论】:

    【解决方案3】:

    我真的很讨厌这个,我经常看到这个,但我想我的意思不够清楚,所以我会自己回答我的问题,对不起!

    我的一个朋友问我:“你不能使用字段列表,而不是逐个传递它们吗?

    好吧,我检查了这个,可以给 onFields() 一个字符串数组(感谢 varargs (...))。

    我将所有字段添加到列表中,并将它们作为参数传递给我的方法。根据给定的条件,可以添加(或不添加)字段。

    例子:

    List<BeitragVO> results;
    
        List<String> fields= new ArrayList<String>();
    
        FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search
                .getFullTextEntityManager(em); // em = entitymanager
    
    
    
        QueryBuilder qb = fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder().forEntity(BeitragVO.class).get();
    
        if (student) {
            fields.add("user.surname");
            fields.add("user.givenname");
        }
        if (company) {
            fields.add("company.name");
        }
    
    
        org.apache.lucene.search.Query luceneQuery = qb.keyword()
                .onFields(fields.toArray(new String[fields.size()]))
                .matching(searchterm).createQuery();
    

    如果 company AND students 为真,则搜索将使用所有三个字段。

    【讨论】:

      猜你喜欢
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多