SolrJ의 사용법을 익히기 위해

Spring + SolrJ + Solr (Lucene) 기반으로 단순 게시판을 구현하였고,

소스는 Github에서 받을 수 있다.

1. Solr로 만드는 단순 게시판: 각종 설치

2. SolrJ 사용법

3. Solr 단순 게시판 (CRUD)

4. Solr 페이징과 검색


이전 예제는 Solr 서버에 대한 데이터 입출력(CRUD)을 익히기 위한 예제로

간단한 단순 게시판을 구현하였고,

여기에서는 검색 엔진인 Solr 서버의 기능을 조금 더 익히기 위해

페이징과 검색 기능을 구현한다.


페이징과 검색은 게시판 예제 중 제법 고급 기능으로

게시판에 대한 조금은 깊은 이해가 필요하다.

다만 이 글은 Solr에 대한 사용법을 익히는 것이 목적이기 때문에

게시판과 관련된 설명은 간단하게 정리하니

Java로 구현된 게시판의 정리 내용을 읽어보면 도움이 될 것이다.


먼저 페이징(Paging) 기능을 구현한다.

페이징은 다음 그림의 하단에서 보듯이 주어진 데이터를 나누어서 출력하는 것을 의미한다.

많은 데이터를 하나의 웹 페이지 출력하면 시간과 메모리 등의 문제가 발생히 때문에,

지정된 개수(10, 20개 등) 만큼 조회해서 출력한다.

페이징 처리에 대한 구체적인 구현 방법은 제법 복잡해서 여기에서는 정리하지 않고,

두 가지 기본 개념만 간단하게 정리하면

주어진 데이터의 개수를 출력할 데이터 개수(10, 20개 등)로 나누어

전체 페이지 수를 계산해서 화면에 출력한다.

예로, 데이터가 100 개면 10 개의 페이지가 출력된다.


현재 페이지가 지정되면 (리스트에서 사용자가 클릭하면)

계산을 해서 조회할 데이터의 시작 번호를 찾게 되고

이 번호 이후의 데이터를 지정한 개수만큼 가져와 출력한다.


이외에 상세한 정보는 Java(Spring) 게시판 예제의 정리를 참고하면 된다.


Board2Ctr.java

기존에 사용한 코드 (board1List)에 몇 가지를 추가하여 구현하였다.

추가한 코드는 데이터의 개수를 세어 [라인 9~12]

페이지를 계산하고 [라인 13],

시작 데이터와 조회할 데이터 개수를 지정하는 코드이다 [라인 16, 17].


개수를 세는 조회(Query)에는 데이터 반환이 필요 없기 때문에

반환 할 데이터 개수를 0 으로 지정한다 (setRows(0)) [라인 9].

총 데이터의 개수(getNumFound)만 확인하여 [라인 12],

PageVO의 pageCalculate() 함수에 파라미터로 제공하여 계산한다 [라인 13].

pageCalculate() 함수와 페이징에 대한 상세한 설명은

Java(Spring) 게시판 예제의 정리를 참고 하면 된다.


이 함수를 실행하고 나면

PageVO 클래스의 rowStart에 시작번호가 지정되어 있기 때문에

getRowStart() 함수로 가져와서 -1 하였다 [라인 16].

이 클래스는 자바 게시판 예제에서 작성한 것으로

애초 개발이 Oracle 기반으로 제작되었고,

Oracle에서는 데이터 시작 번호를 1 부터 한다.

Solr 에서는 0 부터 시작하기 때문에 PageVO를 수정하지 않고 -1로 구현하였다.


setRows() 함수로 가져올 데이터 개수를 지정하였다 [라인 17].


이렇게 실행된 데이터(docs)와 페이지 정보(pageVO)를

Jsp로 넘겨서 화면에 출력한다 [라인 21, 22].

/board2/boardList.jsp


화면 출력은 페이지 번호를 출력하는 forEach 문만 이해하면 된다 [라인 3].

forEach문은 앞서 글 리스트의 화면(boardList.jsp)에서 사용하는 것처럼

지정된 데이터(배열)의 개수만큼 반복처리하는 것이 있고,

여기에서 사용한 것처럼 시작 값(pageStart)부터 종료 값(pageEnd)까지 반복하는 기능이 있다.


데이터가 10,000개이고 10개씩 출력할 경우,

페이지가 1,000개가 되기 때문에 모두 출력할 수 없어

페이지 번호(시작페이지와 종료페이지)에 대하여 페이징을 하게 된다.

PageVO 클래스에 있는 pageCalculate()함수에서

시작페이지(pageStart)부터 종료페이지(pageEnd)를 계산해 준다.

이 값을 하나씩 i 변수에 넣어서 페이지 번호를 출력한다 [라인 3].


부가적으로 새로운 글 번호를 출력하도록 했다.

앞서의 리스트 그림을 보면

날짜와 시간으로 된 긴 글 번호(brdno) 값 대신에

11 부터 2 까지의 새로운 번호가 출력된 것을 볼 수 있다.

내부적으로는 날짜와 시간으로 된 글 번호(brdno) 값으로 처리하지만

사용자에게 보여주는 값은 정리된 일련번호를 보여주는 것이다.

다음 코드를 사용해 보고 계산식은 각자 확인해 보길 바란다.

<c:forEach var="listview" items="${listview}" varStatus="status">   
    <tr>
        <td><c:out value="${pageVO.totRow-((pageVO.page-1)*pageVO.displayRowCount + status.index)}"/></td>
        <td><a href="${link}"><c:out value="${listview.brdtitle[0]}"/></a></td>
        <td><c:out value="${listview.brdwriter[0]}"/></td>
        <td><fmt:formatDate pattern = "yyyy-MM-dd" value = "${listview.brddate[0]}" /></td>
    </tr>
</c:forEach>

/board2/boardList.jsp


이번에는 실제 검색에서 사용되는 기능과 유사한 게시판의 검색 기능을 구현한다.

실제 검색은 더 많은 필드들을 복잡한 조건으로 구현하고,

여기서는 다음 그림의 아랫 부분에 있는 것처럼

게시판의 제목과 내용 필드에 대하여

검색하려고 하는 값(검색 키워드)을 이용하여 조회(Query)하는 기능을 구현한다.

구현 방법은 글 읽기에서 작성했던 것처럼

Solr의 setQuery() 함수에 조건을 지정하여 구현한다.

글 읽기에서는 검색할 필드와 값을 “:”으로 구분하여 지정하였다.

예: 글번호:1      =>     id:1


여기에서는 사용자가 선택한 필드와 값(검색키워드)를 이용하여

다음과 같은 문장을 생성하여 조건으로 사용하면 된다.

제목:검색키워드 AND 내용:검색키워드

=>   brdtitle:HTML AND brdmemo:HTML


/board3/boardList.jsp

이해를 위해 화면 처리 부분을 먼저 정리한다.

검색 결과에 대해서도 페이징 처리를 구현해야 하기 때문에

검색 필드(checkbox)와 키워드(text), 현재 페이지 번호(hidden)를 가지고 다녀야 한다.

이 각각의 값을 Get방식으로 전달하기 보다는

Post 방식이 더 쉽기 때문에 Form 태그를 사용하였고, [라인 1].

코드를 줄여서 보이기 위해, 앞서 구현한 페이징을 별도의 파일로 처리하였다 [라인 2].


HTML에서 두 개의 체크 박스를 같은 이름(searchType)으로 지정하면

Java에서 콤마(,)로 받게 된다.

첫 번째 체크 박스는 brdtitle [라인 5],

두 번째 체크 박스는 brdmemo [라인 7]

로 값(Value 속성)을 지정하고,

사용자가 둘다 선택하면 [brdtitle, brdmemo]로 Java에 전달된다.

이 값을 searchType 변수로 받아서

다시 화면에 출력할 때 선택된 상태로 보일 때 사용한다.

즉, searchType 변수 값에 brdtitle 문자열이 있으면(indexOf>-1)

해당 체크 박스가 체크 표시(checked)가 되도록 한다 [라인 5].

글 내용(brdmemo)도 동일하게 구현한다 [라인 7].


화면 처리와 관련하여 보다 상세한 설명은 Java 게시판 예제의 정리를 참고하면 된다.


Board3Ctr.java

컨트롤에서는 Solr 서버에서 원하는 데이터를 가지고 올 수 있도록 검색 조건을 생성한다.

4 라인부터15 라인까지의 내용이 조건을 위해 추가한 코드이다.


사용자가 체크박스에서 선택한 내용을 searchType으로 받아서 [라인 4]

콤마(,)로 분류하여 각 선택 값을 배열로 변환한다 [라인 7].

이 배열의 개수만큼 반복해서 [라인 8]

필드명과 검색 키워드(searchKeyword)를 콜론(:)으로 구분하여 조건을 생성한다.

조건과 조건은 AND로 묶었다 [라인 9]

(OR로 처리해도 된다. 개념상 OR가 더 적당하다)


이렇게 생성한 조건(queryStr)을

글읽기에서 사용한 것처럼 setQuery로 지정하면 된다 [라인 17].


주의 : 코어만 생성하고 Solr를 실행한 경우 한국어 검색은 제대로 실행 되지 않을 수 있다.

형태소 분석기 등을 추가하고, 필드 설정을 제대로 해야 한다.

자세한 내용은 설정 부분을 참고하면 된다.


이상으로 Solr와 SolrJ의 사용법을 익히기 위해

Spring 4 + MyBatis 3 + MariaDB로 제작한 게시판 예제 중 몇 가지를

MariaDB 대신에 Solr 서버를 데이터 베이스처럼 사용해서 구현했다.

게시판과 관련된 설명들은 자세하게 정리하지 않았으니

기존 게시판 예제의 정리를 읽어보길 바란다.


나머지 예제들 (총 8 가지의 게시판이 있음)도 구현해보면

Solr에 대한 이해를 높일 수 있고,

프로그래밍 실력을 향상시키는데 도움이 될 것이다.



'서버 > 검색엔진' 카테고리의 다른 글

3. Solr 예제 분석 - 스키마(Schema)  (0) 2020.01.12
4. Solr 예제 분석 - DIH  (0) 2020.01.12
1. Solr로 만드는 단순 게시판: 각종 설치  (18) 2017.08.24
2. SolrJ 사용법  (0) 2017.08.24
3. Solr 단순 게시판 (CRUD)  (0) 2017.08.24

+ Recent posts