2.4. 루신 쿼리

이 절에서는 루신 모듈의 쿼리 기능을 설명한다.

2.4.1. Maven integration

Querydsl 루신을 사용하려면 루신 3은 querydsl-lucene3 모듈을 그리고 루신 4는 querydsl-lucene4 모듈을 사용한다.

루신 3:

<dependency>
  <groupId>com.mysema.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>

루신 4:

<dependency>
  <groupId>com.mysema.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>

2.4.2. 쿼리 타입 생성

다음과 같은 방식으로 year와 title 필드를 가진 쿼리 타입을 직접 작성할 수 있다.

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는 year와 title 필드를 가진 루신 Document를 표현한다.

루신의 경우 스키마 데이터를 사용할 수 없기 때문에 코드 생성 기능을 사용할 수 없다.

2.4.3. 쿼리

Querydsl 루신으로 쿼리하는 것은 간단하다.

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"))
    .list();

위 코드는 다음의 루신 쿼리로 바뀐다.

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

2.4.4. 일반 용법

LuceneQuery 클래스의 cascading 메서드는 다음과 같다.

where: 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. PStrings에 수행되는 오퍼레이션을 지원한다. (matches, indexOf, charAt은 제외). 현재 in은 지원되지 않으며, 향후 지원할 예정이다.

orderBy: 정렬 표현식을 이용해서 정렬 순서를 지정한다. 숫자나 문자열에 대해서는 asc()나 desc()를 사용하고, OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다.

limit, offset, restrict: 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, restrict는 limit과 offset을 함께 정의한다.

2.4.5. 정렬

정렬 구문은 다음과 같다.

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

위 코드는 다음 루신 쿼리와 동일하다.

title:*

title과 year의 오름차순으로 결과를 정렬한다.

sort 메서드와 Sort 인스턴스를 사용해서 정렬을 지정할 수 있다.

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

2.4.6. 결과 개수 제한

결과 개수 제한은 다음과 같이 한다.

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

2.4.7. 오프셋

오프셋은 다음과 같이 지정한다.

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

2.4.8. 퍼지(fuzzy) 검색

com.mysema.query.lucene.LuceneExpressions 클래스에서 정의된 fuzzyLike 메서드를 이용해서 퍼지 검색을 할 수 있다.

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

2.4.9. 루신 필터를 쿼리에 적용하기

단일 루신 필터를 쿼리에 적용할 수 있다.

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

distinct 필터링을 위한 distinct(Path) 메서드를 제공한다.

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