2.5. Querying Lucene

This chapter describes the querying functionality of the Lucene module.

2.5.1. Maven integration

Querydsl Lucene can be used via the querydsl-lucene3 module for Lucene 3, querydsl-lucene4 for Lucene 4 and querydsl-lucene5 for Lucene 5

Lucene 3:

<dependency>
  <groupId>com.querydsl</groupId>
  <artifactId>querydsl-lucene3</artifactId>
  <version>${querydsl.version}</version>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.1</version>
</dependency>

Lucene 4:

<dependency>
  <groupId>com.querydsl</groupId>
  <artifactId>querydsl-lucene4</artifactId>
  <version>${querydsl.version}</version>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.1</version>
</dependency>

Lucene 5:

<dependency>
  <groupId>com.querydsl</groupId>
  <artifactId>querydsl-lucene5</artifactId>
  <version>${querydsl.version}</version>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.1</version>
</dependency>

2.5.2. Creating the query types

With fields year and title a manually created query type could look something like this:

public class QDocument extends EntityPathBase<Document> {
    private static final long serialVersionUID = -4872833626508344081L;

    public QDocument(String var) {
        super(Document.class, PathMetadataFactory.forVariable(var));
    }

    public final StringPath year = createString("year");

    public final StringPath title = createString("title");
}

QDocument represents a Lucene document with the fields year and title.

Code generation is not available for Lucene, since no schema data is available.

2.5.3. Querying

Querying with Querydsl Lucene is as simple as this:

QDocument doc = new QDocument("doc");

IndexSearcher searcher = new IndexSearcher(index);
LuceneQuery query = new LuceneQuery(true, searcher);
List<Document> documents = query
    .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle"))
    .fetch();

which is transformed into the following Lucene query:

+year:[1800 TO 2000] +title:huckle*

2.5.4. General usage

Use the the cascading methods of the LuceneQuery class like this

where: Add the query filters, either in varargs form separated via commas or cascaded via the and-operator. Supported operations are operations performed on PStrings except matches , indexOf , charAt . Currently in is not supported, but will be in the future.

orderBy: Add ordering of the result as an varargs array of order expressions. Use asc() and desc() on numeric, string and other comparable expression to access the OrderSpecifier instances.

limit, offset, restrict: Set the paging of the result. Limit for max results, offset for skipping rows and restrict for defining both in one call.

2.5.5. Ordering

The syntax for declaring ordering is

query
    .where(doc.title.like("*"))
    .orderBy(doc.title.asc(), doc.year.desc())
    .fetch();

which is equivalent to the following Lucene query

title:*

The results are sorted ascending based on title and year.

Alternatively a sort method call can be used to declare the sort logic as a Sort instance instead

Sort sort = ...;
query
    .where(doc.title.like("*"))
    .sort(sort)
    .fetch();

2.5.6. Limit

The syntax for declaring a limit is

query
    .where(doc.title.like("*"))
    .limit(10)
    .fetch();

2.5.7. Offset

The syntax for declaring an offset is

query
    .where(doc.title.like("*"))
    .offset(3)
    .fetch();

2.5.8. Fuzzy searches

Fuzzy searches can be expressed via fuzzyLike methods in the com.querydsl.lucene3.LuceneExpressions class:

query
    .where(LuceneExpressions.fuzzyLike(doc.title, "Hello"))
    .fetch();

2.5.9. Applying Lucene filters to queries

It is possible to apply a single Lucene filter to the query like this:

query
    .where(doc.title.like("*"))
    .filter(filter)
    .fetch();

A shortcut for distinct filtering is provided via the distinct(Path) method:

query
    .where(doc.title.like("*"))
    .distinct(doc.title)
    .fetch();