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.

This commit is contained in:
Vesa Martilla 2010-03-24 11:36:03 +00:00
parent c50d9571c4
commit a776e6eb43
2 changed files with 201 additions and 17 deletions

View File

@ -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<LuceneQuery>, SimpleProjectable<Document>{
@ -40,9 +40,6 @@ public class LuceneQuery implements SimpleQuery<LuceneQuery>, 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<LuceneQuery>(this);
this.serializer = serializer;
@ -75,13 +72,16 @@ public class LuceneQuery implements SimpleQuery<LuceneQuery>, 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<LuceneQuery>, SimpleProjectable<
@Override
public List<Document> list() {
List<OrderSpecifier<?>> 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<Document> documents = new ArrayList<Document>();
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<LuceneQuery>, SimpleProjectable<
return documents;
}
private List<Document> listSorted(List<OrderSpecifier<?>> orderBys) {
private List<Document> listSorted(List<OrderSpecifier<?>> orderBys, int limit, int offset) {
List<Document> documents = new ArrayList<Document>();
List<SortField> sortFields = new ArrayList<SortField>();
for (OrderSpecifier<?> orderSpecifier : orderBys) {
@ -123,9 +135,9 @@ public class LuceneQuery implements SimpleQuery<LuceneQuery>, 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<LuceneQuery>, SimpleProjectable<
@Override
public SearchResults<Document> listResults() {
// TODO : implement
throw new UnsupportedOperationException();
List<Document> documents = list();
return new SearchResults<Document>(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!");
}

View File

@ -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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> 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<Document> documents = query.list();
assertFalse(documents.isEmpty());
assertEquals(4, documents.size());
}
}