Transcript 루씬1

Lucene
송호연
연구개발팀
2015-01-19
목차
1. Lucene
3. 검색
1-1 정의 및 개발과정
3-1 IndexSearcher
1-2 검색 애플리케이션의 구조
3-2 QueryParser 검색어 파싱
1-3 검색확보 소프트웨어 소개
3-3 다양한 종류의 질의
3-4 연관도 점수
3-5 예제
2. 색인(Index)
2-1 indexWriter & 색인문서
2-2 색인 락
2-3 색인 최적화
2-4 준실시간 검색
2-5 Directory
2-6 Analyzer
2-7 Document & Field
2-8 예제
Lucene
1-1
정의
* 내용
- 무료로 사용할 수 있는 오픈소스 프로젝트이며, 아파치 소프트웨어 재단에서 아파치 소프트웨어 라이센스
스로 배포중이다.
- 파일 시스템 형태의 검색 기능을 추가할 수 있게 도와주는 jar 자바 검색 라이브러리라 별도의 의존성이 없
다.
- 자바 언어로 만들어 졌지만, 여러 종류의 프로그래밍 언어로 포팅되어 다른 언어와 연동할 수 있다.(C,
C++, C#, 루비, 펄, 파이썬, PHP 등)
- http://lucene.apache.org/
- http://www.acornpub.co.kr/book/lucene-2nd
개발과정
* 내용
- 최초 더그 커팅이(하둡) 개발했으며, 처음에는 소스포지(SourceForge)사이트의 루씬 프로젝트에서 내려 받
을 수 있었다.
- 2001년 9월 오픈소스 자바 프로젝트를 제공하던 아파치 재단의 자카르타 프로젝트의 일원으로 합류
- 2005년 여러 개발자 들이 참여하면서 아파치 재단의 취상위 프로젝트가 됐
다.(http://lucene.apache.org/java)
1-2
검색 애플리케이션
의 구조
* 내용
- 원본파일을 가져와 루씬 문서의 형태로 변환
- 변환된 텍스트를 색인에 추가(토큰화, 정형화, 동의어/기본형 처리)
- 사용자 인터페이스를 통해 사용자가 찾고자 하는 검색어를 루씬 질의로 변환
- 루씬 질의를 실행해 결과를 받아오고 화면에 출력
- 검색대상 확보와 관련한 기능은 포함하지 않아 별도의 소프트웨어(솔라, 너치 등)와의 연동이 필요하다
사용자
검색화면 인터페이스
검색 질의 생성
결과 출력
질의 생성
관
리
인
터
페
이
스
색인
색인에 문서 추가
문서 텍스트 분석
루씬 문서 생성
검색 대상 텍스트 확보
검색대상
분
석
인
터
페
이
스
1-3
검색확보 소프트웨
어 소개
* 내용
- 솔라(Solr, http://lucene.apache.org/solr) : 아파치 루씬 프로젝트에 속한 오픈소스 프로젝트이며, 관계형
데이터베이스나 XML 파일 등의 내용을 수집하는 기능을 갖고 있다. 특히 티카 프로젝트와 연동해 다양한 종
류의 파일에서 텍스트를 추출해 활용할 수 있다. (성능의 이유로 색인 공유가 아닌 색인 복제)
- 너치(Nutch, http://lucene.apache.org/nutch) : 솔라와 함께 아파치 루씬 프로젝트에 속해 있으며, 대용량
웹문서 수집 기능을 갖고 있다.
- 그럽(Grub, http://sourceforge.net/projectsgrub) : 오픈소스 웹 문서 수집 프로젝트
- 헤리트릭스(Herirtix) : 인터넷 아카이브(http://crawler.archive.org)에서 사용하는 웹문서 수집기
- 드로이드(Droids, http://incubator.apache.org/droids) : 아파치 루씬 프로젝트에 속해 있으며, 아파치 인
큐베이션 절차(아파치 사이트내 템플릿 보고 제안서를 작성)를 진행하고 있다.
- 애퍼처(Apertur, http://aperture.sourceforge.net) : 웹사이트와 파일시스템, 메일함 등의 내용을 수집하고
텍스트를 추출하는 기능을 갖고 있다.
- 구글 엔터프라이즈 커넥터 매니저(Goole Enterprise Connector Manaager,
http://code.google.com/p/google-enterprise-connector-manager) : 웹사이트가 아닌 여러 종류의 저장
소에 접근해 대 상 문서를 확보할 수 있다.
색인(Index)
2-1
색인(Index)
* 내용
- 엄청난 양의 대상 문서에서 원하는 내용을 빠르게 검색하고자 할 때 원본 문서를 색인하고 검색하기 좋은 형
태로 변환해 색인으로 만들어 두면 사용자가 검색어를 입력할 때마다 순차적으로 파일을 읽어가며 원하는 내
용이 있는지 확인할 필요가 있는데, 이런 처리 작업을 색인이라 하며, 색인 작업을 거친 결과문 역시 색인 이라
고 한다. 즉, 특정 단어로 직업 이동할 수 있는 자료 구조라고 할 수 있으며, 여러 개의 색인 파일 형태로 파일 시
스템에 저장한다.
Architecture
* 내용
HTML
이메일 메시지
일반 문서
텍스트
추출
텍스트
추출
텍스트
추출
분석
색인
2-2
IndexWriter
* 내용
- IndexWriter 에서는 색인을 새로 생성하거나 기존 색인을 열고 문서를 추가하거나 삭제하거나 변경하는
기능을 담당한다.
- IndexWriter 클래스는 색인을 변경하는 기능을 갖고 있지만 IndexWriter 클래스로 색인의 내용을 검색하
거나 꺼내 볼 수는 없다.
- IndexWriter는 색인을 저장할 공간이 필요하며, 색인을 저장하는 공간은 Directory 클래스로 표현한다.
IndexWriter indexWriter = new IndexWriter(directory, new Analyzer(),
IndexWriter.MaxFieldLength.UNLIMITED);
2-1
색인문서
* 내용
- 색인 문서 추가 : 텍스트, 숫자, 시간 색인 가능
- addDocument(Document) : IndexWriter 를 생성할 때 지정한 기본 분석기를 사용해 문서를 색인에 추가
한다.
- addDocument(Document, Analyzer) : 인자로 지정한 분석기를 사용해 문서를 색인 한다. 이렇게 문서마다
분석기를 직접 지정할 때는 주의해야 한다. 색인 할 때 지정한 분석기와 검색할 때 사용한 분석기가 서로 다르
면 검색결과가 다르게 나올 수 있는 가능성이 높다.
IndexWriter writer = getWriter();
Document doc = new Document();
writer.addDocment(doc);
* 내용
- 색인 문서 삭제
- deleteDocuments(Term) : 메소드는 지정한 텀을 포함하는 모든 문서를 삭제한다.
- deleteDocuments(Term[]) : 메소드는 지정한 텀 중 하나라도 포함하는 모든 문서를 삭제한다.
- deleteDocuments(Query) : 메소드는 지정한 질의에 해당하는 모든 문서를 삭제한다.
- deleteDocuments(Query[]) : 메소드는 지정한 질의에 배열에 담긴 질의 중 어느 것에 라도 해당하는 모든
문서를 삭제한다.
- deleteAll() : 메소드는 해당 색인에 들어 있는 모든 문서를 삭제한다.
IndexWriter writer = getWriter();
Document doc = new Document();
writer.deleteDocment(new Term(“id”, “똥쌔기”));
2-1
색인문서
* 내용
- 색인 문서 변경 : update 같지만 실질적으로는 delete 후 insert 과정을 거친다.
- updateDocument(Term, Document) : 메소드는 인자로 지정한 Term 객체에 해당하는 모든 문서를 삭제
하고, 해당 IndexWriter 에 기본 설정된 분석기를 사용해 지정한 문서를 추가한다.
- updateDocument(Term, Document, Analyzer) : 메소드는 지정한 Term 객체에 해당하는 모든 문서를 삭
제하고, 인자로 지정한 분석기를 사용해 지정한 문서를 추가한다.
IndexWriter writer = getWriter();
Document doc = new Document();
writer.updateDocument(new Term(“id”, “1”), doc);
2-2
색인 락
* 내용
- 색인 하나에 하나의 IndexWriter만 접근할 수 있게 루씬은 파일 기반의 락을 사용한다. 색인 디렉토리에
락파일(write.lock)이 존재한다는 이야기는 이미 쓰기 권한을 쥐고 있다는 뜻이다.
- IndexWriter를 생성하거나 IndexReader에서 변경기능을 사용하려 하면 LockObtainFailedException이
발생하며 색인이 깨지지 않게 막아주는 예외 상황이다.
- 루씬에서는 LockFactory 클래스를 상속받아 새로운 클래스를 구현하고 원하는대로 락을 지정할 수 있지
만, 여러건을 신청한 순서대로 처리하는 등의 큐가 없어 락을 공정하게 처리하려면 락 생성 클래스를 직접
구현해야 한다.
Direcotry
설명
NativeFSLockFactory
FSDirectory 클래스에서 사용하는 기본 락이며, java.nio 패키지를 통
해 운영체제에서 제공하는 락 기능을 활용한다. 따라서 JVM 이 종료
될 때 락 파일이 남을 염려가 없다. 하지만 NFS(NetWork File System)
를 비롯해 파일 시스템에 따라 제대로 동작하지 않을 가능성도 있다.
SimpleFSLcokFactory
자바의 File.createNewFile() 메소드를 사용해 락 파일을 생성하며, 따
라서 NativeFSLockFactory보다 시스템의 종류에 영향을 덜 받는다.
하지만 문제가 발생해 JVM이 비정상 종료되거나 JVM 이 종료 할 때
IndexWriter를 제대로 닫지 못했다면 write.lock 파일이 남아 있을 수
있다. 이렇게 락 파일이 남아 있는 경우 수동으로 직접 제거해야 한다.
SingleInstanceLockFactory
락을 메모리 안에 생성한다. RAMDirectory를 사용하는 경우 기본 설
정으로 사용한다. 모든 IndexWriter가 동일한 JVM 안에서 생성될 때
만 제대로 사용할 수 있다.
NoLockFactory
락을 사용하지 않는다. 루씬이 제공하는 락을 사용할 필요가 없다고 판
단되는 경우에만 사용해야 한다. 예를 들어 특정 객체에서 내부적으로
RAMDirectory를 생성하고 단 하나의 IndexWriter 인스턴스만 사용하
는 등의 경우에만 제한적으로 사용하는 편이 좋다.
2-3
색인 최적화
* 내용
- 문서를 색인할 때 특히 대량의 문서를 색인하거나 IndexWriter 인스턴스를 여러 개 열어 색인하는 경우 결과
적으로 색인에 세그먼트의 개수가 많아진다. 세그먼트가 많은 색인을 검색할 때 루씬은 각 세그먼트를 개별적
으로 열고 검색하며, 각 세그먼트의 검색 결과를 취합해 사용한다. 색인하고 검색하는 과정에는 아무런 문제가
없지만, 수많은 세그먼트로 구성된 색인의 경우 최적화 과정을 거쳐 세그먼트의 개수를 최소화하면 검색 속도
를 향상시킬 수 있다. 최적화 작업은 검색 속도를 향상시켜주지만, 색인 속도에는 영향이 없다.
- optimize() : 색인의 세그먼트를 하나로 병합해 최적화하며, 병합작업이 끝날 때까지 리턴하지 않는다.
- optimize(int maxNumSegments) : 부분 최적화라고도 부르며, 세그먼트를 maxNumSegments 인자의 개
수 이하로 병합한다. 일반적으로 병합 과정에서 마지막에 단 하나의 세그먼트를 생성할 때 시간이 많이 소모
되기 때문에 병합 시간을 최소화하면서 최적화의 장점도 얻을 수 있다.
- optimze(boolean doWait) : optimize() 메소드와 동일하지만, doWait 인자에 false 값을 지정하면 병합 작
업을 백그라운드 스레드에서 진행하고 optimize(boolean doWait) 메소드는 즉시 리턴해 다른 작업을 처리할
수 있다. 다만 doWait 인자에 False 값을 지정하려면 ConcurrentMergeScheduler 처럼 병합 작업을 백그라
운드로 실행하는 스케줄러를 사용하고 있어야 한다.
- optimize(int maxNumSegments, boolean doWait) : 병합 작업을 백그라운드 스레드로 실행 하면서 최대
세그먼트 개수도 지정할 수 있다.
IndexWriter writer = getWriter();
writer.deleteDocuments(new Term("id", "1"));
writer.optimize();
2-4
준실시간 검색
* 내용
- 루씨 버전 2.9 부터 핵심 기능 중 준실시간 검색 기능이 추가됐다. 루씬에서는 IndexWriter 의 다음 메소드
를 통해 준실시간 검색을 지원한다.
IndexReader.getReader()
- 위 메소드를 호출하면 버퍼에 들어있던 추가 또는 삭제된 문서를 색인에 모두 반영한 다음 반영된 내용을 담
고 있는 IndexReader 인스턴스를 리턴한다. 루씬 내부적으로 getReader() 메소드를 통해 받아오는
IndexReader 객체는 기존에 열려있던 세그먼트 정보를 그대로 사용하며, 새로 추가되거나 변경된 세그먼트
만 새로 읽어 들이기 때문에 매우 효율적으로 빠르게 생성할 수 있다.
2-5
Directory
* 내용
- 루씬의 색인을 저장하는 공간을 나타낸다.
- Directory 클래스 자체는 추상 클래스이며, 색인을 저장할 공간에 따라 Directory 클래스를 상속받아 필요한
메소드를 구현해야 한다
Direcotry
설명
SimpleFSDirectory
색인을 파일 시스템에 저장하는 가장 기본적인 Directory 클래스.
Java.io.* 패키지의 기능을 활용하며 동시에 사용하려는 스레드 개수가
많아지면 성능이 떨어진다.
NIOFSDirectory
색인을 파일 시스템에 저장하지만 java.nio.* 패키지의 기능을 활용한
다. 동시에 사용하려는 스레드의 개수가 많아져도 성능이 크게 떨어지
지 않지만, 마이크로소프트 윈도우 운영체제에서는 JRE 의 문제점 때
문에 성능이 떨어진다.
MMapDirectory
메모리 맵 I/O 기능을 활용해 파일의 내용을 읽어오는 Directory 클래
스. 64비트 JRE 를 사용하고 있다면 괜찮은 선택이며, 색인의 크기가
충분히 작다면 32비트 JRE를 사용해도 문제는 없다.
RAMDirectory
모든 파일을 메모리에 보관하는 Directory 다.
FilSwitchDirectory
두개의 디렉토리를 사용하며, 파일 확장자에 따라 두개의 디렉토리를
바꿔가며 사용한다.
Directory ramDir = new SimpleFDSirectory(otherDir);
2-6
Analyzer
* 내용
- 본문이나 제목 등의 텍스를 색인하기 전에 반드시 분석기를 통해 단어로 분리해야 하며, 이를 토큰화 한다고
도 하며 일반적으로 토큰은 사람이 눈으로 보는 단어에 해당된다.
- 지정된 텍스트를 색인할 단위 단어로 분리하고 필요 없는 단어를 제거하는 등의 역할을 담당한다. (토큰화,
정형화, 동의어/기본형 처리)
토큰
문서
필드
분석
필드
분석
색인에 추가
필드
색인
2-6
Analyzer
Field
설명
WhitespaceAnalyzer
텍스트를 공백문자 기준으로 토큰으로 분리하며, 기타 토큰을 정규화하는
작업은 전혀 하지 않는다. 심지어 대소문자도 변경하지 않는다.
SimpleAnalyzer
알파벳이 아닌 모든 글자 기준으로 토큰을 분리하고, 각 토큰을 모두 소문
자로 변경한다. 일반 글자는 그대로 남아있지만, 숫자도 모두 제거 한다는
점을 유의해야 한다.
StopAnalyzer
SimpleAnalyzer 와 비슷하지만 StopAnalyzer는 추가적으로 불용어를 제
거한다. 기본설정으로 영어의 불용어 (the. a 등을)를 제거하지만, 원한다면
불용어 목록을 별도로 지정할 수도 있다.
StandardAnalyzer
텍스트를 분석해 회사이름, 이메일 주소, 도메인 이름 등의 다양한 토큰을
인식하고 별도로 분리한다. 그리고 토큰의 알파벳을 모두 소문자로 변경하
고, 불용어도 제거하고, 특수 기호도 모두 제거한다.
Analyzing “XY&Z Corporation – [email protected]”
WhitespaceAnalyzer : [XY&Z] [Corporation] [-] [[email protected]]
SimpleAnalyzer :
[xy] [z] [corporation] [xyz] [example] [com]
StopAnalyzer :
[xy] [z] [corporation] [xyz] [example] [com]
StandardAnalyzer :
[xy&z] [corporation] [[email protected]]
2-6
Analyzer
유사 발음 검색
* 내용
- 아파치 커먼스 코덱 프로젝트에 들어 있는 메타폰 알고리즘을 사용해 단어의 발음 기본형을 찾아내는 분석
기.
- 실제로 특별한 경우를 제외하고 사용되는 경우는 없지만, 사용자가 입력한 검색어에 대한 결과를 찾을 수 없
을때 발음이 유사한 단어를 조회해 검색어를 추천하기도 한다.
-메타 알고리즘은 cool, kool, col 은 모두 KL로 인코딩한다.
Analzer analyzer = new MetaphoneReplacementAnalyzer();
Public calss MetaphoneReplacementAnalyzer extends Analyzer{
public TokenStream tokenStream(String fieldName, Reader reader){
return new MetaphoneReplacementFilter(new LetterTokenizer(reader))
}
}
2-7
Document
* 내용
- Document 클래스는 개별 필드의 집합이다
- Document 클래스는 가상의 문서라고 생각 할 수 있는데, 웹 페이지나 이메일 메시지, 텍스트 파일, 단순한
텍스트 등 검색 결과로 받아 보려는 결과 단위를 뜻한다
- 문서의 메타 정보(ex: 저자, 제목, 날짜 등)는 본문과 서로 다른 필드도 동일한 문서에 함께 담아 색인할 수 있
다.
Document doc = new Document();
Field
* 내용
- 색인의 각 문서는 모두 두 개 이상의 각자 이름이 지정된 개별 필드로 구성되며, 각 필드는 Field라는 클래스
로 표현한다.
-모든 필드는 각자의 이름과 값이 들어 있다.
-필드별로 여러 설정을 지정할 수 있고, 루씬은 필드마다 지정된 설정에 따라 해당 필드의 값을 색인한다.
doc.add(new Field(“id”, “1”, Field.Store.YES, Field.Index.NO))
2-7
Field 속성
* 색인관련 설정
Field
설명
Index.ANALYZED
필드에 지정된 텍스트를 분석기에 넘겨 일련의 토큰을 뽑아내 각 토큰
을 검색 할 수 있게 한다.(제목, 요약 등)
Index.NOT_ANALYZED
필드에 지정된 텍스트를 검색하게 역파일 색인에 추가하긴 하지만, 분
석기로 텍스르를 처리하진 않는다. 즉, 텍스트 전체를 텍스트 전체를 하
나의 토큰으로 간주해 색인에 넣는다. 웹페이지의 URL이나 파일 시스
템의 절대 경로, 날짜, 사람 이름, 주민등록번호, 전화번호 처럼 분리
하지 않고 하나로 사용해야 할 값에 적용한다.
Index.ANALYZED_NO_NORM
Index.ANALYZED와 비슷한 설정이지만, norm 값을 색인에 저장하지
않는다. Norm 값은 색인할 때 지정했던 중요도를 색인에 보관 하지만,
검색할 때 메모리를 좀 더 많이 소모한다.
Index.NOT_ANALYZED_NO_N
ORM
Index.ANALYZED와 비슷한 설정이지만 norm 값을 색인에 저장하지
않는다. 색인이 차지하는 용량과 검색 시점의 메모리 사용량을 절약하
고자 할때 사용한다.
Index.NO
해당 필드에 지정한 본문 텍스트는 색인하지 않는다.
* 원문저장 관련 설정
Field
설명
Store.YES
필드의 텍스트를 색인에 그대로 저장한다. 나중에 IndexReader를 통
해 다시 그대로 받아올 수 있다. 주로 검색 결과를 화면에 표시할 때 사
용할 값에 Store.YES 설정을 지정하면 유용하다
Store.NO
필드의 텍스트를 색인에 저장하지 않는다. Store.NO 설정은 주로
Index.ANALYZED 설정과 함께 사용하며, 필드의 내용을 검색해야하
긴 하지만 결과 화면에 보여줄 필요가 없는 내용인 경우에 사용한
다.(웹페이지의 본문, 본문 전체)
2-8
예제
* 내용
- IndextingTest.java 참조
검색
3-1
검색
* 내용
- 색인에 들어 있는 토큰을 기준으로 해당하는 토큰이 포함된 문서를 찾아내는 과정을 말한다.
- 검색의 품질은 흔히 정확도와 재현율로 표현하기도 한다.
- 정확도는 검색 시스템에서 사용자가 입력한 검색어와 관련 없는 문서를 얼마나 정확하게 제거하는지를 뜻한
다.
클래스
검색 핵심 클래스
설명
IndexSearcher
색인을 검색하는 기능을 담당하는 클래스. 모든 검색 기능은
IndexSearcher 인스턴스의 여러가지 searcher 메소드를 통해 진행한
다
Query(하위클래스 포함)
실제 Query 하위 클래스에서 특정 질의 기능을 구현한다.
IndexSearcher 의 search() 메소드에 Query 객체를 직접 인자로 넘겨
줄 수 있다.
QueryParser
사람이 직접 입력하고 사람이 한눈에 알아볼 수 있는 텍스트 형태의
질의를 분석해 루씬 Query 객체로 변환한다.
TopDocs
IndexSearcher.search() 메소드에서 검색한 결과 중 연관도 점수가 가
장 높은 결과 문서를 담는 클래스다.
ScoreDoc
TopDocs 클래스에 담긴 검색 결과 하나를 나타내는 클래스.
3-1
IndexSearcher
* 내용
- IndexSearcher 클래스는 색인을 읽기 전용으로 열어 사용한다.
- 검색 메소드는 Query 객체와 결과로 받을 문서의 개수 topN을 인자로 지정하고 TopDocs 객체를 결과로 넘
겨 받는다.
- IndexReader 인스턴스를 새로 만들때 자원을 많이 소모한다. 따라서 가능한 대로 IndexReader를 최대한 재
사용해야 하며, indexReader 를 새로 만드는 일은 최소화해야 한다.
Directory dir = FSDirectory.open(new File(“/tmp/index”));
IndexSearcher searcher = new IndexSearcher(dir);
Query q = new new TermQuery(new Term(“contents”, “lucene”));
TopDocs hits = searcher.search(q, 10);
Searcher.close();
IndexReader newReader = reader.reopen();
Query
IndexSearcher
IndexReader
Directory
색인
TopDocs
3-1
QueryParser
검색어 파싱
* 내용
- 사용자가 입력한 ‘mock OR junit’ 같은 텍스트 질의를 분석해 동일한 의미의 Query 객체로 변환한다는 뜻이
다. mock OR junit’ 검색어를 QueryPaser로 파싱하면 두개의 텀 질의를 담고 있는 하나의 질의 결과를 얻게
된다.
Query 객체
검색어
QueryParser
IndexSearcher
분석된 개별언어
Analyzer
- QueryParser 를 통해 사용자가 입력한 텍스트 형태의 검색어를 루씬에서 인식하는 Query 객체로 변환한다.
QueryParser parser = new QueryParser(Version.LUCENE_30, “contents”, new SimpleAnalyzer());
Query query1 = parser.parse(“+JUNIT +ANT -MOCK”);
Query query2 = parser.parse(“mock OR junit”);
TopDocs doc = searcher.search(query1, 10);
TopDocs doc = searcher.search(query2, 10);
3-1
다양한 종류의 질의
* 내용
- TermQuery : 특정단어를 포함하는 문서를 찾는 기본적인 Query, 대소문자를 구분한다.
Term t = new Term(“isbn”, “908043980924”);
Query query = new TermQuery(t);
TopDocs docs = search.search(query, 10);
- TermRangeQuery : 원하는 범위의 텀을 검색, 시작하는 텀과 종료 텀은 각각 검색 결과에 포함하거나 제외
시킬 수 있으며, 문자열 범위 검색에 유용.(ex : 알파벳으로 이름찾기 등)
//true 는 시작점과 종료점의 범위를 포함할 것인지 제외할 것인지를 지정
TermRangeQuery query = new TermRangeQuery(“title”, “d”, “j”, true, true);
TopDocs docs = search.search(query, 100);
3-1
다양한 종류의 질의
* 내용
- NumericRangeQuery : 원하는 범위의 색인된 숫자를 검색할 수 있으며, 단순한 텀에 비해 트라이 구조의 공
간 개수가 상대적으로 적기 때문에 비슷한 TermRangeQuery 보다 속도가 훨씬 빠르다
//true 는 시작점과 종료점의 범위를 포함할 것인지 제외할 것인지를 지정
NumericRangeQuery query = new NumericRangeQuery(“month”, 200605, 200609, true, true);
TopDocs docs = search.search(query, 100);
- PrefixQuery : 지정한 문자열로 시작하는 모든 텀을 갖고 있는 문서를 찾아준다. 계층적인 정보의 검색에 유
용하다.
Term term = new Term (“category”, /technology/computers/programming);
PrefixQuery query = new PrefixQuery(term)
TopDocs docs = search.search(query, 100);
3-1
다양한 종류의 질의
* 내용
- BooleanQuery : 다양한 종류의 질의는 모두 BooleanQuery를 통해 복잡한 형태로 묶어 사용할 수 있다.
BooleanQuery 안에 들어가는 각 질의는 절이라고 부른다.
TermQuery searchingBooks = new TermQuery(new Term("subject","search"));
Query books2010 = NumericRangeQuery.newIntRange("pubmonth", 201001, 201012, true, true);
BooleanQuery searchingBooks2010 = new BooleanQuery();
searchingBooks2010.add(searchingBooks, BooleanClause.Occur.MUST);
searchingBooks2010.add(books2010, BooleanClause.Occur.MUST);
/* BooleanClause.Occur.MUST : 지정한 질의만 검색
* BooleanClause.Occur.SHOULD : 지정한 질의는 해당하면 좋고, 해당하지 않더라도 다른조건에 맞는다면 검색
* BooleanClause.Occur.MUST_NOT : 지정한 질의에 해당하는 문서는 제외하고 검색
*/
- WildcardQuery : 단어를 완벽히 모르는 상태에서 검색을 가능케 한다. ‘*’ 와일드 카드는 글자가 없거나 하
나 이상의 여러 글자에 대응하고, ‘?’ 와일드카드는 글자가 없거나 아니면 하나에 해당한다. 접두어로 와일드
카드를 사용하면 색인의 모든 텀을 조회해야 하기 때문에 서능이 떨어진다.
Query query = new WildcardQuery(new Term(“contents”, “?ild*”));
TopDocs docs = search.search(query, 100);
3-1
다양한 종류의 질의
* 내용
- FuzzyQuery : 질의에 지정한 단어와 비슷한 단어를 찾아준다. 레벤스타인 거리 알고리즘을 사용해 색인의
단어와 질의의 단어 사이의 거리를 계산하고 비슷한 단어인지 확인한다. 색인된 모든 텀을 대상으로 편집거리
를 계산하기에 필요한 경우에만 사용하도록 한다.
(http://en.wikipedia.org/wiki/Levenshtein_Distance)
Query query = new FuzzyQuery(new Term(“contents”, “wuzza”));
TopDocs docs = search.search(query, 100);
- MatchAllDocsQuery : 색인에 들어있는 모든 문서를 검색 결과로 가져온다. 기본 설정으로 모든 결과 문서
에 각 문서의 중요도 값을 유사도 점수로 지정한다. 그리고 기본 유사도 점수를 기준으로 정렬하는 대신 별도
의 필드를 기준으로 정렬하는 편이 좋다.
Query query = new MatchALLDocsQuery(field);
TopDocs docs = search.search(query, 100);
3-1
연관도 점수
* 내용
- 검색 과정에서 질의에 해당하는 문서를 찾아낼 때마다 해당 문서가 질의에 얼마나 비슷하게 일치하는지 점
수를 부여한다.
- 점수는 문서와 질의가 얼마나 비슷한지를 숫자로 표현한 값이며, 점수가 높을 수록 연관도가 높다 할 수 있다.
- 유사도 점수는 질의(q)와 텀(t), 문서(d)를 기준으로 계산한다
- explain() 메소드를 통해 점수 내역을 확인 할 수 있다
항목
설명
tf(t in d)
문서(d)의 텀(t)에 대한 텀 빈도수(TF, TermFrequency), 즉 해당 문서에서 텀이 몇번
이나 나타나는지를 뜻한다.
Idf(t)
해당 텀의 역문서 빈도수(IDF, Inverse Document Frequency), 텀이 얼마나 독보적인
지를 나타낸다. 찾아보기 어려운 단어일수록 idf 값이 높다
boost(t.field in d)
색인할 때 지정했던 필드와 문서의 중요도 값이다. 중요도를 지정하면 다른 문서나 필
드에 비해 특정 문서나 필드가 더 높은 유사도 점수를 받는다
lengthNorm(t.field in d)
V필드 안에 속한 텀의 개수를 정규화한 값이다. 이 값은 색인과정에 게산해서 문서와
함께 색인에 보관한다. 이 항목으로 인해 필드 원문의 길이가 짦은 문서가 더 높은 유
사도 점수를 얻는다.
coord(q, d)
질의에 지정된 텀 중 특정 문서에 포함된 텀의 개수에 따라 정해지는 조율
(coordination) 항목이다. 조율 항목을 통해 상대적으로 질의에 해당하는 텀을 더 많
이 포함하고 있는 문서가 더 높은 유사도 점수를 받는다
queryNorm(q)
질의의 각 텀에서 중요도의 제곱 합을 정규화한 값이다.
2-5
예제
* 내용
- Searcher.java 참조
감사합니다.
참고자료
* 내용
참고자료 관련링크
- http://lucene.apache.org/
- http://www.acornpub.co.kr/book/lucene-2nd
- http://www.itworld.co.kr/news/78212
- http://cafe.naver.com/korlucene