From a776e6eb43f49e0887be0e358d254b49ed011c5d Mon Sep 17 00:00:00 2001 From: Vesa Martilla Date: Wed, 24 Mar 2010 11:36:03 +0000 Subject: [PATCH] Added support for LuceneQuery.listResult, limit, offset and restrictions are now taken into consideration as well in LuceneQuery.list* methods. Created tests for these cases. --- .../com/mysema/query/search/LuceneQuery.java | 44 +++-- .../mysema/query/search/LuceneQueryTest.java | 174 +++++++++++++++++- 2 files changed, 201 insertions(+), 17 deletions(-) diff --git a/querydsl-lucene/src/main/java/com/mysema/query/search/LuceneQuery.java b/querydsl-lucene/src/main/java/com/mysema/query/search/LuceneQuery.java index 01becc828..4f6225910 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/search/LuceneQuery.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/search/LuceneQuery.java @@ -29,7 +29,7 @@ import com.mysema.query.types.expr.EBoolean; /** * LuceneQuery is a Querydsl query implementation for Lucene queries - * + * * @author vema */ public class LuceneQuery implements SimpleQuery, SimpleProjectable{ @@ -40,9 +40,6 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< private final Searcher searcher; - // TODO Is there an alternative for this? - private static final int MAX_RESULT_COUNT = 30000; - public LuceneQuery(LuceneSerializer serializer, Searcher searcher) { this.queryMixin = new QueryMixin(this); this.serializer = serializer; @@ -75,13 +72,16 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< } private Query createQuery() { + if (queryMixin.getMetadata().getWhere() == null) { + throw new QueryException("Where clause was null."); + } return serializer.toQuery(queryMixin.getMetadata().getWhere()); } @Override public long count() { try { - return searcher.search(createQuery(), MAX_RESULT_COUNT).totalHits; + return searcher.search(createQuery(), searcher.maxDoc()).totalHits; } catch (IOException e) { throw new QueryException(e); } @@ -95,15 +95,27 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< @Override public List list() { List> orderBys = queryMixin.getMetadata().getOrderBy(); + Long queryLimit = queryMixin.getMetadata().getModifiers().getLimit(); + Long queryOffset = queryMixin.getMetadata().getModifiers().getOffset(); + int limit; + int offset = queryOffset != null ? queryOffset.intValue() : 0; + try { + limit = searcher.maxDoc(); + } catch (IOException e) { + throw new QueryException(e); + } + if (queryLimit != null && queryLimit.intValue() < limit) { + limit = queryLimit.intValue(); + } if (!orderBys.isEmpty()) { - return listSorted(orderBys); + return listSorted(orderBys, limit, offset); } List documents = new ArrayList(); try { - ScoreDoc[] scoreDocs = searcher.search(createQuery(), MAX_RESULT_COUNT).scoreDocs; - for (ScoreDoc scoreDoc : scoreDocs) { - documents.add(searcher.doc(scoreDoc.doc)); + ScoreDoc[] scoreDocs = searcher.search(createQuery(), limit + offset).scoreDocs; + for (int i = offset; i < scoreDocs.length; ++i) { + documents.add(searcher.doc(scoreDocs[i].doc)); } } catch (IOException e) { throw new QueryException(e); @@ -111,7 +123,7 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< return documents; } - private List listSorted(List> orderBys) { + private List listSorted(List> orderBys, int limit, int offset) { List documents = new ArrayList(); List sortFields = new ArrayList(); for (OrderSpecifier orderSpecifier : orderBys) { @@ -123,9 +135,9 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< Sort sort = new Sort(); sort.setSort(sortFields.toArray(new SortField[sortFields.size()])); try { - ScoreDoc[] scoreDocs = searcher.search(createQuery(), null, MAX_RESULT_COUNT, sort).scoreDocs; - for (ScoreDoc scoreDoc : scoreDocs) { - documents.add(searcher.doc(scoreDoc.doc)); + ScoreDoc[] scoreDocs = searcher.search(createQuery(), null, limit + offset, sort).scoreDocs; + for (int i = offset; i < scoreDocs.length; ++i) { + documents.add(searcher.doc(scoreDocs[i].doc)); } } catch (IOException e) { throw new QueryException(e); @@ -145,14 +157,14 @@ public class LuceneQuery implements SimpleQuery, SimpleProjectable< @Override public SearchResults listResults() { - // TODO : implement - throw new UnsupportedOperationException(); + List documents = list(); + return new SearchResults(documents, queryMixin.getMetadata().getModifiers(), documents.size()); } @Override public Document uniqueResult() { try { - ScoreDoc[] scoreDocs = searcher.search(createQuery(), MAX_RESULT_COUNT).scoreDocs; + ScoreDoc[] scoreDocs = searcher.search(createQuery(), searcher.maxDoc()).scoreDocs; if (scoreDocs.length > 1) { throw new QueryException("More than one result found!"); } diff --git a/querydsl-lucene/src/test/java/com/mysema/query/search/LuceneQueryTest.java b/querydsl-lucene/src/test/java/com/mysema/query/search/LuceneQueryTest.java index c6cb9a40a..d4a9d1807 100644 --- a/querydsl-lucene/src/test/java/com/mysema/query/search/LuceneQueryTest.java +++ b/querydsl-lucene/src/test/java/com/mysema/query/search/LuceneQueryTest.java @@ -21,6 +21,8 @@ import org.junit.Before; import org.junit.Test; import com.mysema.query.QueryException; +import com.mysema.query.QueryModifiers; +import com.mysema.query.SearchResults; import com.mysema.query.types.path.PString; import com.mysema.query.types.path.PathBuilder; @@ -84,6 +86,11 @@ public class LuceneQueryTest { searcher.close(); } + @Test(expected = QueryException.class) + public void count_Empty_Where_Clause() { + query.count(); + } + @Test public void count() { query.where(title.eq("Jurassic Park")); @@ -91,7 +98,13 @@ public class LuceneQueryTest { } @Test - public void list() { + public void countDistinct() { + query.where(year.like("19*").or(title.like("The Lord*"))); + assertEquals(3, query.countDistinct()); + } + + @Test + public void list_Sorted_By_Year_Ascending() { query.where(year.between("1800", "2000")); query.orderBy(year.asc()); List documents = query.list(); @@ -99,6 +112,66 @@ public class LuceneQueryTest { assertEquals(4, documents.size()); } + @Test + public void list_Not_Sorted() { + query.where(year.between("1800", "2000")); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_Not_Sorted_Limit_2() { + query.where(year.between("1800", "2000")); + query.limit(2); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_Sorted_By_Year_Limit_1() { + query.where(year.between("1800", "2000")); + query.limit(1); + query.orderBy(year.asc()); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(1, documents.size()); + } + + @Test + public void list_Not_Sorted_Offset_2() { + query.where(year.between("1800", "2000")); + query.offset(2); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_Sorted_Ascending_By_Year_Offset_2() { + query.where(year.between("1800", "2000")); + query.offset(2); + query.orderBy(year.asc()); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_Sorted_Ascending_By_Year_Restrict_Limit_2_Offset_1() { + query.where(year.between("1800", "2000")); + query.restrict(new QueryModifiers(2l, 1l)); + query.orderBy(year.asc()); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1954", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + @Test public void list_Sorted_Ascending_By_Year() { query.where(year.between("1800", "2000")); @@ -166,4 +239,103 @@ public class LuceneQueryTest { query.uniqueResult(); } + @Test + public void listDistinct() { + query.where(year.between("1900", "2000").or(title.startsWith("Jura"))); + query.orderBy(year.asc()); + List documents = query.listDistinct(); + assertFalse(documents.isEmpty()); + assertEquals(3, documents.size()); + } + + @Test + public void listResults() { + query.where(year.between("1800", "2000")); + query.restrict(new QueryModifiers(2l, 1l)); + query.orderBy(year.asc()); + SearchResults results = query.listResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals("1990", results.getResults().get(1).get("year")); + assertEquals(2, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(2, results.getTotal()); + } + + @Test + public void listDistinctResults() { + query.where(year.between("1800", "2000").or(title.eq("The Lord of the Rings"))); + query.restrict(new QueryModifiers(1l, 1l)); + query.orderBy(year.asc()); + SearchResults results = query.listDistinctResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals(1, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(1, results.getTotal()); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Sorted_Ascending_Limit_Negative() { + query.where(year.between("1800", "2000")); + query.limit(-1); + query.orderBy(year.asc()); + query.list(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Not_Sorted_Limit_Negative() { + query.where(year.between("1800", "2000")); + query.limit(-1); + query.list(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Sorted_Ascending_Limit_0() { + query.where(year.between("1800", "2000")); + query.limit(0); + query.orderBy(year.asc()); + query.list(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Not_Sorted_Limit_0() { + query.where(year.between("1800", "2000")); + query.limit(0); + query.list(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Sorted_Ascending_Offset_Negative() { + query.where(year.between("1800", "2000")); + query.offset(-1); + query.orderBy(year.asc()); + query.list(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_Not_Sorted_Offset_Negative() { + query.where(year.between("1800", "2000")); + query.offset(-1); + query.list(); + } + + @Test + public void list_Sorted_Ascending_Offset_0() { + query.where(year.between("1800", "2000")); + query.offset(0); + query.orderBy(year.asc()); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_Not_Sorted_Offset_0() { + query.where(year.between("1800", "2000")); + query.offset(0); + List documents = query.list(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } }