public void testStraightFilters() { createData(); FullTextSession s = Search.getFullTextSession(openSession()); s.getTransaction().begin(); BooleanQuery query = new BooleanQuery(); query.add(new TermQuery(new Term("teacher", "andre")), BooleanClause.Occur.SHOULD); query.add(new TermQuery(new Term("teacher", "max")), BooleanClause.Occur.SHOULD); query.add(new TermQuery(new Term("teacher", "aaron")), BooleanClause.Occur.SHOULD); FullTextQuery ftQuery; ftQuery = s.createFullTextQuery(query, Driver.class); ftQuery.enableFullTextFilter("bestDriver"); Filter dateFilter = new TermRangeFilter("delivery", "2001", "2005", true, true); ftQuery.setFilter(dateFilter); assertEquals("Should select only liz", 1, ftQuery.getResultSize()); ftQuery = s.createFullTextQuery(query, Driver.class); ftQuery.setFilter(dateFilter); ftQuery.enableFullTextFilter("bestDriver"); ftQuery.enableFullTextFilter("security").setParameter("login", "andre"); ftQuery.disableFullTextFilter("security"); ftQuery.disableFullTextFilter("bestDriver"); ftQuery.setFilter(null); assertEquals("Should not filter anymore", 3, ftQuery.getResultSize()); s.getTransaction().commit(); s.close(); deleteData(); }
/** * 全文检索 * * @param page 分页对象 * @param query 关键字查询对象 * @param queryFilter 查询过滤对象 * @param sort 排序对象 * @return 分页对象 */ @SuppressWarnings("unchecked") public Page<T> search(Page<T> page, BooleanQuery query, BooleanQuery queryFilter, Sort sort) { // 按关键字查询 FullTextQuery fullTextQuery = getFullTextSession().createFullTextQuery(query, entityClass); // 过滤无效的内容 if (queryFilter != null) { fullTextQuery.setFilter(new CachingWrapperFilter(new QueryWrapperFilter(queryFilter))); } // 设置排序 if (sort != null) { fullTextQuery.setSort(sort); } // 定义分页 page.setCount(fullTextQuery.getResultSize()); fullTextQuery.setFirstResult(page.getFirstResult()); fullTextQuery.setMaxResults(page.getMaxResults()); // 先从持久化上下文中查找对象,如果没有再从二级缓存中查找 fullTextQuery.initializeObjectsWith( ObjectLookupMethod.SECOND_LEVEL_CACHE, DatabaseRetrievalMethod.QUERY); // 返回结果 page.setList(fullTextQuery.list()); return page; }
/** * 生成Hibernate的FullTextQuery全文搜索对象。 * * @return 返回Hibernate的FullTextQuery全文搜索对象。 */ public FullTextQuery generateQuery() { FullTextQuery fullTextQuery = session.createFullTextQuery(generateLuceneQuery(), clazz); if (!sortFields.isEmpty()) { for (SortField sortField : sortFields) { if (!searchFields.containsKey(sortField.getField())) { throw new HibernateException("全文搜索时指定的排序字段 " + sortField.getField() + " 必须包含在搜索字段中"); } } fullTextQuery.setSort(new Sort(sortFields.toArray(new SortField[] {}))); } if (filter != null) { fullTextQuery.setFilter(filter); } if (criteriaQuery != null) { fullTextQuery.setCriteriaQuery(criteriaQuery); } return fullTextQuery; }
/** * Skip elements, values of which repeat in the given field. * * <p>Only the first element will be included in the results. * * <p><b>Note:</b> For performance reasons you should call this method as last when constructing a * query. When called it will project the query and create a filter to eliminate duplicates. * * @param field * @return */ public LuceneQuery<T> skipSame(String field) { String idPropertyName = getSession().getSessionFactory().getClassMetadata(getType()).getIdentifierPropertyName(); List<Object> documents = listProjection(idPropertyName, field); Set<Object> uniqueFieldValues = new HashSet<Object>(); TermsFilter termsFilter = new TermsFilter(); for (Object document : documents) { Object[] row = (Object[]) document; if (uniqueFieldValues.add(row[1])) { termsFilter.addTerm(new Term(idPropertyName, row[0].toString())); } } buildQuery(); fullTextQuery.setFilter(termsFilter); return this; }