Solr의 사용법을 익히기 위해

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

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

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

2. SolrJ 사용법

3. Solr 단순 게시판 (CRUD)

4. Solr 페이징과 검색


게시판을 만들기 위해서는

MariaDB 와 같은 DBMS에서 데이터를 저장하는

다음과 같이 테이블(TBL_BOARD)을 생성해야 한다.

CREATE TABLE TBL_BOARD (

    BRDNO int(11) NOT NULL AUTO_INCREMENT,         -- 글 번호

    BRDTITLE varchar(255),                                -- 제목

    BRDWRITER varchar(20),                              -- 작성자

    BRDMEMO   varchar(4000),                           -- 내용

    BRDDATE     datetime,                                -- 작성일자

    PRIMARY KEY (BRDNO)
) ;

기본적인 게시판을 구현하기 위해서는 이상의 5 개의 필드가 필요하고,

Solr에서 정의하는 방법은 설정 부분에서 정리하였다.

여기에서는 이러한 설정을 하지 않고 코어(solrBoard)만 생성해서 진행한다.

데이터를 저장할 때 Solr에서 자동으로 생성되는 기능을 이용하였다.

입력 값에 따라서 다음과 같이 자동으로 생성된다.

  <field name="brdtitle" type="strings"/>
  <field name="brdwriter" type="strings"/>
  <field name="brdmemo" type="strings"/>
  <field name="brddate" type="tdates"/>

대부분 위에서 정의한 필드 구조로 생성되지만

글 번호(BRDNO)는 키 필드(PRIMARY KEY)로

데이터 값을 유일하게(Unique) 유지하는 역할을 하는데 Solr에서 별도로 설정을 해야 한다.

여기에서는 설정을 생략하기 위해 코어 생성시 기본 지정되는 ID 필드를 이용한다.

HTML이나 VO 클래스에서는 BRDNO로 사용하고

SolrJ를 이용하여 저장하거나 조회 때에는 ID라는 이름으로 사용한다.



게시판의 기능 중 글 리스트를 먼저 구현한다.

Java에서 board1List 컨트롤을 다음과 같이 작성한다.

Board1Ctr.java

이상의 코드는 모두 SolrJ 사용법 중 데이터 조회 부분에 정리되어 있다.

여기에서는 기본 예제로

Solr 서버에 있는 모든 데이터를 가지고 와서 출력하도록 했기 때문에

설명에 사용된 코드를 그대로 사용하였다.

차이는 ModelMap을 이용하여

Solr 서버에서 가지고온 데이터(docs)를

listview라는 이름으로 Jsp로 넘겨 주는 것이다 [라인 10].


/board1/boardForm.jsp

대부분의 코드는 디자인을 위한 HTML 코드이고

주어진 데이터를 화면에 출력하는 코드는 18 라인부터 29라인이다.

주어진 데이터(listview)의 개수 만큼  반복(forEach)해서

각 행(tr)을 생성하여 출력한다.


listview는 ModelMap으로 컨트롤(Java)에서 주어진 데이터 이고

Jsp(HTML)에서는 [listview.변수]로 사용하면 된다 [라인 24~27].


다만 키인 id를 제외하고

나머지 필드는 모두 배열[]로 처리되어 있다.

필드 정의에서 multiValued가 true로 지정되었기 때문으로 [설치 참조]

별도로 지정하지 않으면 true가 기본값으로 사용된다.


작성일자(brddate)에 형식(formatDate) 태그를 사용한 것은 [라인 27]

Solr 서버가 주어진 데이터(yyy-mm-dd)를 날짜로 인식해서

tdates 형으로 지정해서 저장하기 때문이다.

tdates 형으로 지정하면 [Sat Aug 19 09:00:00 KST 2017]로 출력한다.

작성일자(brddate)를 managed-schema에서 string으로 지정하는 것이 좋지만

여기서는 형식(formatDate) 태그를 이용하여 처리하였다.


주의: 게시판 예제는 필드 정의를 하지 않았다는(solr만 시작) 전제로 작성되었다.

만약, 설치에서 정리한 데로 필드를 정의하였다면,

brddate를 날짜형(tdates )이 아닌 문자열(String)로 지정되어 있기 때문에

27 라인에서 오류가 발생한다.

27 라인을 다음과 같이 수정하여야 한다.

<td><c:out value="${listview.brddate}"/></td>

필드 정의 부분의 주의 사항을 읽어보길 바란다.


톰캣을 실행하고

웹 브라우저에서 다음과 같이 입력해서 실행을 확인한다.

http://localhost:8080/solrBoard/board1List


이번에는 글 쓰기 기능을 구현한다.

게시판 글 쓰기는 글을 작성하기 위한 폼(board1Form)과

작성된 내용을 저장하는 부분(board1Save)으로 구성된다.


Board1Ctr.java

여기에서는 글쓰기와 글 수정을 하나로 구성했기 때문에

조금 복잡하게 보이지만 단순한 개념이다.

글 쓰기 폼은 아무 것도 하지 않고 입력 받을 HTML을 화면에 출력한다.

글 수정 폼은 지정된 글 번호(brdno)에 해당하는 내용을 찾아서 (getOneboard) [라인 5]

입력 상자에 초기값으로 넣어준다.


Solr에서 데이터를 가지고 오는 것은

글 읽기와 동일하기 때문에 getOneboard() 함수로 작성하였다.

상세한 내용은 글 읽기에서 정리하였으니 넘어간다.

/board1/boardForm.jsp

글 내용을 작성한 뒤에

글 저장(board1Save)을 호출하기 위해

Form 태그에서 action으로 지정하였다 [라인 1].


컨트롤의 getOneboard()함수에서

지정된 글에 대한 정보를 boardInfo에 넣어서 반환했기 때문에

Jsp에서도 [boardInfo.변수]로 사용한다 [라인 11, 15, 19, 24, 25].


두 개의 HTML HIDDEN 태그가 사용하였다 [라인 21, 22].

글 번호(brdno)는 글쓰기 일때는 값이 없고

글 수정일때는 값이 있게 되어,

저장시(board1Save ) 신규 등록과 수정의 기준이 된다.


작성일자(brddate)를 HIDDEN 태그로 가지고 있는 것은 Solr의 특성때문이다.

글 내용을 저장할 때 지정된 필드만 수정하는 것이 아니고

행 자체를 수정하기 때문에

수정되지 않았어도 같이 필드 값을 주지 않으면

빠진 필드는 빈 값으로 채워진다.

따라서 입력 받지 않는 작성일자도 값을 가지고 있다가 [라인 22]

같이 board1Save 컨트롤로 넘겨 준다.

작성일자는 Solr에서 [Sat Aug 19 09:00:00 KST 2017]으로 반환되기 때문에

yyyy-mm-dd로 변환해서 가지고 있는다 [라인 22].


웹 브라우저에서 다음 주소를 입력하여 실행을 확인 할 수 있다.

http://localhost:8080/solrBoard/board1Form



[저장]을 선택하면 오류가 날 뿐 저장되지 않는다.

Solr 서버에 데이터를 저장하는 컨트롤(board1Save)을 작성해야 한다.

다음 코드 중 핵심 코드는 SolrJ 사용법에서 정리하였다.

Board1Ctr.java

Solr 서버에 데이터를 저장하기 위해

SolrJ로 SolrInputDocument 클래스를 사용하여 저장한다 [라인 9~18].


사용자가 입력한 값을 boardInfo로 받아서 [라인 2]

SolrInputDocument 에 넣어준다[라인 9~14].

다만, 키 필드를 id로 지정했기 때문에 글 번호(brdno)를 id로 지정하였다 [라인 10].


이상의 코드는 SolrJ 사용법에서 정리한 내용과 동일하고

차이나는 부분은 글 번호(brdno)와 작성일자(brddate)의 값을 생성하는 부분이다.

이 두 필드는 사용자가 입력하는 값이 아니고

프로그램에서 생성하는 값이기 때문이다.


먼저, 작성일자는 SimpleDateFormat 클래스를 사용하여

현재 서버의 시간을 yyyy-MM-dd형식으로 저장하도록 했다.


글번호는 조금의 트릭을 사용하였다.

글번호는 데이터 저장 공간(테이블) 내에서 유일한 값(Primary key, Unique)을 가져야 한다.

DBMS에서는 최대 글번호에 1씩 증가하여 유일한 값을 유지한다.

Solr에는 이러한 기능이 없기(?) 때문에 날짜를 이용하여 생성하였다 [라인 30].

서버의 시간을 밀리센컨드로 받아서 [라인 31]

1~10까지의 숫자 중 아무 숫자랑(random) 결합하여 유일한 값을 생성하였다 [라인 32].

서버 성능에 따라 중복 값이 발생할 수 있지만 테스트 용으로는 무난하게 사용할 수 있다.


다음으로 글 읽기(baord1Read) 기능을 구현한다.

Board1Ctr.java

글읽기는 글 수정과 같이

주어진 글 번호에 대한 상세 정보를 조회하여 화면에 출력한다.

따라서 getOneboard() 함수를 작성하고

이 함수를 각각의 컨트롤에서 호출하여 구현하였다.


주어진 글 번호에 대한 상세 정보를 조회하는 코드는

데이터를 찾는 것이기 때문에 글 리스트와 동일하다

차이점은 주어진 글 번호를 조건으로 한다는 점이다.

(실제로는 글 리스트는 글 본문을 조회하지 않고, 글읽기는 조회한다는 차이도 있다)


글 번호를 조건(Query)으로 하기 위해

setQuery 함수의 파라미터에 조건("id:" + brdno)을 지정하였다 [라인 11].

글 리스트에서는 조건을 전체 데이터("*:*")로 지정하였다.


조회 결과 반환된 데이터(docs)가 [라인 15]

1개 이상을 반환할 수 있기 때문에 배열로 반환된다.

글 읽기는 하나의 데이터(행)만 있으면 되기 때문에,

Jsp로 해당 글 정보를 넘기기 전에 docs의 get() 함수를 이용하여

첫(0) 번째 데이터를 boardInfo라는 이름으로 지정하였다 [라인 19].


/board1/boardForm.jsp

글 읽기 화면(jsp)에서는 컨트롤에서 주어진 값들을(boardInfo) 출력한다.

글 쓰기 폼과 유사하게 작성하고,

디자인 구성이나 입력받기 위한 태그(text, textarea)를 사용하는 차이가 있다.



마지막으로 글 삭제(baord1Delete) 기능을 구현한다.


Board1Ctr.java

글 삭제는 코드와 같이 매우 간단하다.

deleteByQuery() 함수를 이용하여

삭제할 때 조건으로 사용할 필드와 값을 지정하면 된다.


글 읽기에서 삭제 버튼을 눌러서 잘 실행되는지 확인한다.


이것으로 Solr를 이용한 단순 게시판을 구현하였다.

웹 브라우저에서 다음 주소를 입력하여 실행을 확인 할 수 있다.

http://localhost:8080/solrBoard/board1List




이상의 내용을 Solr의 입장에서 정리하면

게시판 글 쓰기(수정)와 삭제는 색인 작업(Indexing)이 되고,

글 리스트와 글 읽기는 검색 작업(Query)이 된다.

즉, 검색 엔진의 가장 중요한 기능은 색인과 검색으로

여기에서는 SolrJ로 Solr의 색인과 검색을 제어하는 간단한 방법들을 정리하였다.




+ Recent posts