이 주제에 대한 마지막 글입니다.
이전에 Indexing 부분까지 작성하고 까먹고 있었네요.. --ㅋ
이전 포스트까지
문서를 Indexing하고 해당 문서를 저장하여 두는 Store까지 살펴보았습니다.
간단하게 요약하면 문서의 내용을
분석하여 키워드를 추출하고, 그 키워드를 필드별로 해당 키워드를 가진
문서번호(내부적인 unique number)와 연결하여 인덱스 파일에 저장해두는 개념이었습니다.
그렇다면 검색은 어떤 방식일까요?
키워드를 통해 위 인덱스파일에서
문서번호를 검색하여 리턴하는 구조가 될 것 입니다.
IndexSearcher.java
인덱스파일은 변경이 될 수 있도록 외부에서 인덱스파일을 셋팅 할 수 있도록 하였습니다.
소스의 간소화를 위해 "제목"과 "본문" 필드에 대해서 키워드로 검색을 수행하도록
하드코딩하였습니다.
그리고 and검색을 위해 제목에 대한 검색으로 나온 rowid와 필드에 대한 검색으로 나온 rowid를
체크하여 (loop) 확인하고 있습니다. 실제로는 이런식으로는 안 하겠죠.
그리고 getDoc(long) 메서드가 있습니다. 검색결과로 리턴되는 것은 실제로는 문서ID의 리스트입니다.
이 문서ID에 해당하는 실제 문서를 가져오기 위해 사용되는 메서드입니다.
테스트케이스는 아래와 같습니다.
IndexSearcherTest.java
결과
우선 Document를 3개 생성하여 색인 대상 문서를 만들어냅니다.
그리고 색인을 하게 되죠. 결과를 보시면 추출된 키워드와 키워드별로 연결된 문서ID가 로깅되는 것을
확인 하실 수 있습니다. 본문과 제목필드에 대해서 모두 수행이 되지요.
테스트는 "운동화"라는 검색어로 진행됩니다.
AND검색으로 수행이 되어 최종적으로 0, 1번 문서가 리턴되는 것을 보실 수 있고
해당 ID의 문서를 IndexSearcher의 getDoc(Long) 메서드를 통해서 가져와서 로깅하는 것도 확인 가능합니다.
3번에 걸쳐서 간단하게나마 검색엔진의 자료구조를 구현해보았습니다.
실제 검색엔진에서는
훨씬 복잡하고 많은 기능이 있을테고
무엇보다도 중요한 속도와 대용량 처리를 위한 각종 최적화 작업이
코드에 포함되어 있을 것 입니다.
앞서 말씀드렸듯이 검색파트를 맡고 있으면서 신규로 들어오는
후배들을 위한 공부용 코드임을 인지하여주세요~
예제코드는
https://github.com/need4spd/searchengine
에서 받아보시거나 확인하실 수 있습니다.
이전에 Indexing 부분까지 작성하고 까먹고 있었네요.. --ㅋ
이전 포스트까지
문서를 Indexing하고 해당 문서를 저장하여 두는 Store까지 살펴보았습니다.
간단하게 요약하면 문서의 내용을
분석하여 키워드를 추출하고, 그 키워드를 필드별로 해당 키워드를 가진
문서번호(내부적인 unique number)와 연결하여 인덱스 파일에 저장해두는 개념이었습니다.
그렇다면 검색은 어떤 방식일까요?
키워드를 통해 위 인덱스파일에서
문서번호를 검색하여 리턴하는 구조가 될 것 입니다.
IndexSearcher.java
인덱스파일은 변경이 될 수 있도록 외부에서 인덱스파일을 셋팅 할 수 있도록 하였습니다.
소스의 간소화를 위해 "제목"과 "본문" 필드에 대해서 키워드로 검색을 수행하도록
하드코딩하였습니다.
그리고 and검색을 위해 제목에 대한 검색으로 나온 rowid와 필드에 대한 검색으로 나온 rowid를
체크하여 (loop) 확인하고 있습니다. 실제로는 이런식으로는 안 하겠죠.
그리고 getDoc(long) 메서드가 있습니다. 검색결과로 리턴되는 것은 실제로는 문서ID의 리스트입니다.
이 문서ID에 해당하는 실제 문서를 가져오기 위해 사용되는 메서드입니다.
테스트케이스는 아래와 같습니다.
IndexSearcherTest.java
결과
색인 : -----------------------------------------
필드 명 : 본문
키워드 : 조끼 - rowId : [2]
키워드 : 운동화 - rowId : [0, 1]
키워드 : 좋아요 - rowId : [0, 1]
키워드 : 싫어요 - rowId : [2]
키워드 : 아디다스 - rowId : [1]
키워드 : 나이키 - rowId : [0]
키워드 : 청바지 - rowId : [2]
-----------------------------------------
필드 명 : 제목
키워드 : 운동화 - rowId : [0, 1, 2]
키워드 : 아디다스 - rowId : [1]
키워드 : 나이키 - rowId : [0]
키워드 : 청바지 - rowId : [2]
결과 : [0, 1]
resultDoc1 : Document [rowId=0, fieldList=[Field [name=제목, value=나이키 운동화], Field [name=본문, value=나이키 운동화 좋아요]]]
resultDoc2 : Document [rowId=1, fieldList=[Field [name=제목, value=아디다스 운동화], Field [name=본문, value=아디다스 운동화 좋아요]]]
우선 Document를 3개 생성하여 색인 대상 문서를 만들어냅니다.
그리고 색인을 하게 되죠. 결과를 보시면 추출된 키워드와 키워드별로 연결된 문서ID가 로깅되는 것을
확인 하실 수 있습니다. 본문과 제목필드에 대해서 모두 수행이 되지요.
테스트는 "운동화"라는 검색어로 진행됩니다.
AND검색으로 수행이 되어 최종적으로 0, 1번 문서가 리턴되는 것을 보실 수 있고
해당 ID의 문서를 IndexSearcher의 getDoc(Long) 메서드를 통해서 가져와서 로깅하는 것도 확인 가능합니다.
3번에 걸쳐서 간단하게나마 검색엔진의 자료구조를 구현해보았습니다.
실제 검색엔진에서는
훨씬 복잡하고 많은 기능이 있을테고
무엇보다도 중요한 속도와 대용량 처리를 위한 각종 최적화 작업이
코드에 포함되어 있을 것 입니다.
앞서 말씀드렸듯이 검색파트를 맡고 있으면서 신규로 들어오는
후배들을 위한 공부용 코드임을 인지하여주세요~
예제코드는
https://github.com/need4spd/searchengine
에서 받아보시거나 확인하실 수 있습니다.