我在JUnit测试下面构建了一个简单的全文本搜索并结合了过滤器:

@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 ='NEW'的文档。

我尝试仅使用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


任何帮助将非常欢迎。
谢谢 !

最佳答案

所以我终于用过滤器投下了头,不起作用,我也没找到原因!

对于相同情况的用户,请在我的完整搜索功能下方找到,就像一个超级按钮(但没有“过滤器”)一样工作:

  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次全文搜索


希望这对某人有所帮助!

10-08 08:13