2016-04-25 27 views
0

工作,我建立一個簡單的全文搜索與過濾器相結合,下面我的JUnit測試:的Lucene /休眠:@FullTextFilterDef不FilterFactory

@Test 
public void D_testFilterFactory() throws Exception { 

    // get the full text entity manager 
    FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em); 

    // create the query using Hibernate Search query DSL 
    QueryBuilder queryBuilder = fullTextEntityManager 
           .getSearchFactory() 
           .buildQueryBuilder() 
           .forEntity(InspectionMaster.class) 
           .get(); 

    // Build Query ! 
    Query query = queryBuilder.keyword().wildcard().onField("itemDesc").matching("*").createQuery(); 

    FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, InspectionMaster.class); 

    // wrap Lucene query in an Hibernate Query object 
    logService.log("TEST : Test search on itemDesc = '*' return " + fullTextQuery.getResultSize() + " documents"); 

    // test filter ! 
    fullTextQuery.enableFullTextFilter("siteFilter").setParameter("siteID", "NEW"); 
    logService.log("TEST : Test search on itemDesc = '*' with filter on site.siteId = 'NEW' return " + fullTextQuery.getResultSize() + " documents"); 

} 

我的過濾器被宣告實體:

@Entity 
@Indexed 
@FullTextFilterDefs({ 
    @FullTextFilterDef(name = "siteFilter", impl = siteFilterFactory.class) 
}) 
@Table(name="LGIMAS") 
public class InspectionMaster implements Serializable { 

我也建一個filterFactory:

public class siteFilterFactory { 
    private String siteID; 

    /** 
    * injected parameter 
    */ 
    public void setSiteID(String siteID) { 
     this.siteID = siteID; 
    } 

    @Key 
    public FilterKey getKey() { 
     StandardFilterKey key = new StandardFilterKey(); 
     key.addParameter(siteID); 
     return key; 
    } 

    @Factory 
    public Filter getFilter() { 
     Query query = new TermQuery(new Term("site.siteId", siteID)); 
     return new CachingWrapperFilter(new QueryWrapperFilter(query)); 
    } 
} 

當然,現場 「site.siteId」 是一種使嵌入我的實體的編索引字段:

@ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="SITID") 
    @IndexedEmbedded 
    private Site site; 

我有以下回報:

*** LOG [Mon Apr 25 23:28:09 CEST 2016] TEST : Test search on itemDesc = '*' return 18 documents 
*** LOG [Mon Apr 25 23:28:09 CEST 2016] TEST : Test search on itemDesc = '*' with filter on site.siteId = 'NEW' return 0 documents 

不是預期的,我有18個文件在我的表包括site.siteId =「新」兩個文件。

我儘量只使用一個TermQuery,無需過濾: 公共無效C_testFilter()拋出異常{

// get the full text entity manager 
    Session hibernateSession = em.unwrap(Session.class); 
    FullTextSession fullTextSession = Search.getFullTextSession(hibernateSession); 

    BooleanQuery bq = new BooleanQuery(); 
    TermQuery filterNEW = new TermQuery(new Term("site.siteId", "NEW")); 
    bq.add(filterNEW, BooleanClause.Occur.MUST); 
    Query q = new QueryParser(Version.LUCENE_36, "cs-method", new StandardAnalyzer(Version.LUCENE_36)).parse(bq.toString()); 

    org.hibernate.Query hibernateQuery = fullTextSession.createFullTextQuery(q, InspectionMaster.class); 
    logService.log("TEST : Test filter on site.siteId = 'NEW' " + hibernateQuery.list().size() + " documents"); 

} 

有了這個代碼如預期的所有工作:

*** LOG [Mon Apr 25 23:42:49 CEST 2016] TEST : Test filter on site.siteId = 'NEW' 2 documents 

任何幫助將是非常歡迎。 謝謝!

回答

1

所以,我終於與濾波器投降,不工作,我沒有找到爲什麼!

對於那些在同一案件中,發現下面我完整的搜索功能,就像是一個迷人(但沒有「過濾器」):

public Page<InspectionMaster> search(String text, String filterStatus, String filterSite, Pageable pageable) { 

     // get the full text entity manager 
     FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em); 

     // create the query using Hibernate Search query DSL 
     QueryBuilder queryBuilder = fullTextEntityManager 
            .getSearchFactory() 
            .buildQueryBuilder() 
            .forEntity(InspectionMaster.class) 
            .get(); 

     // Add wildcard to always have a full search capability 
     text = "*" + text.toLowerCase() + "*"; 

     // Prepare filter on Status and Site 
     Query filterStatusQuery; 
     if (filterStatus.isEmpty()) { 
      filterStatusQuery = queryBuilder.all().createQuery(); 
     } else { 
      filterStatusQuery = queryBuilder.keyword().onField("status").matching(StatusType.fromDescription(filterStatus)).createQuery(); 
     } 
     Query filterSiteQuery; 
     if (filterSite.isEmpty()) { 
      filterSiteQuery = queryBuilder.all().createQuery(); 
     } else { 
      filterSiteQuery = queryBuilder.keyword().onField("site.siteId").matching(filterSite).createQuery(); 
     } 

     // Prepare full text search 
     Query fullTextQuery = queryBuilder 
         .bool() 
         .should(queryBuilder.keyword().wildcard().onField("site.sitedescription").matching(text).createQuery()) 
         .should(queryBuilder.keyword().wildcard().onField("vendorNr").matching(text).createQuery()) 
         .should(queryBuilder.keyword().wildcard().onField("vendorDesc").matching(text).createQuery()) 
         .should(queryBuilder.keyword().wildcard().onField("itemNr").matching(text).createQuery()) 
         .should(queryBuilder.keyword().wildcard().onField("itemDesc").matching(text).createQuery()) 
         .should(queryBuilder.keyword().wildcard().onField("whmPickLocation").matching(text).createQuery()) 
         .createQuery(); 

     // Build final Query ! 
     Query finalQuery = queryBuilder 
        .bool() 
        .must(filterStatusQuery) 
        .must(filterSiteQuery) 
        .must(fullTextQuery) 
       .createQuery();   

     // wrap Lucene query in an Hibernate Query object 
     FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(finalQuery, InspectionMaster.class); 

     jpaQuery.setFirstResult(pageable.getOffset()); 
     jpaQuery.setMaxResults(pageable.getPageSize()); 

     int resultSize = jpaQuery.getResultSize(); 

     // execute search and return results (sorted by relevance as default) 
     @SuppressWarnings("unchecked") 
     List<InspectionMaster> results = jpaQuery.getResultList();  

    return new PageImpl<>(results, pageable, resultSize); 
    }  

這允許使用「3」條件進行搜索:

  • 1「必須」上的狀態的標準(如過濾器)
  • 1「必須」在現場條件(第二濾波器)上的所有其它字段
  • 1全文檢索

希望這可以幫到別人!