【问题标题】:Hibernate search - handling null in boolean queryHibernate 搜索 - 在布尔查询中处理 null
【发布时间】:2017-01-24 02:13:27
【问题描述】:

是否有处理可选子查询的最佳做法?所以说我的搜索服务有

query = builder.bool().must(createQuery(field1, term1)).must(createQuery(field2, term2)).createQuery();

createQuery(field, term) {
     if(term != null) {
          return builder.keyword().onField(field).matching(term).createQuery();
     }
     return null;
}

如果我使用这样的查询并且术语为空,则使用默认的 QueryBuilder,生成的查询为“+term1 +null”或类似的内容,这会在针对索引执行查询时导致空指针异常.有没有推荐的方法来避免这个问题?我正在考虑自定义 QueryBuilder 但我不确定如何告诉全文会话使用我的实现而不是默认的。我能想到的唯一其他方法是

query;
query1 = createQuery(field1, term1);
query2 = createQuery(field2, term2);

if(query1 != null && query2 != null) {
    query = builder.bool().must(query1).must(query2).createQuery();
} else if(query1 != null && query2 == null) {
    query = query1;
} else if(query1 == null && query2 != null) {
    query = query2;
}

createQuery(field, term) {
     if(term != null) {
          return builder.keyword().onField(field).matching(term).createQuery();
     }
     return null;
}

但是如果有多个子查询,这会很快变得非常混乱。

【问题讨论】:

    标签: java search lucene full-text-search hibernate-search


    【解决方案1】:

    您可能要做的是引入一种方法,其唯一目的是以空安全的方式添加“必须”。 IE。做这样的事情:

    BooleanJunction junction = builder.bool();
    must(junction, createQuery(field1, term1));
    must(junction, createQuery(field2, term2));
    query = junction.createQuery();
    
    void must(BooleanJunction junction, Query query) {
        if (query != null) {
            junction.must(query);
        }
    }
    
    Query createQuery(String field, Object term) {
         if(term != null) {
              return builder.keyword().onField(field).matching(term).createQuery();
         }
         return null;
    }
    

    这将消除 BooleanJunction API 的“流动性”,但由于它只是在顶层,我想它还不错。

    【讨论】:

      【解决方案2】:

      这个呢

          org.json.JSONObject json = new org.json.JSONObject();
          json.put(field1, term1);
          json.put(field2, term2);
          ...
      
      
          bool = builder.bool();
          for (Iterator keys = json.keys(); keys.hasNext();) {
              String field = (String) keys.next();
              String term = (String) json.get(field);
              q = createQuery(field, term);
              if (q != null) {
                  bool.must(q);
              }
          }
          query = bool.createQuery();
      

      如果您有具有不同术语的重复字段,您必须使用这个:

          org.json.JSONObject json = new org.json.JSONObject();
          json.append(field1, term1);
          json.append(field2, term2);
          ...
      
      
          bool = builder.bool();
          for (Iterator keys = json.keys(); keys.hasNext();) {
              String field = (String) keys.next();
              JSONArray terms = (JSONArray) json.get(field);
              for (int i = 0; i < terms.length(); i++) {
                  String term = (String) terms.get(i);
                  q = createQuery(field, term);
                  if (q != null) {
                      bool.must(q);
                  }
              }
          }
          query = bool.createQuery();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-19
        • 2011-09-25
        • 2016-12-30
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-30
        相关资源
        最近更新 更多