본문 바로가기

Lucene

[lucene] 질의분석. QueryParser ..

질의를 파싱하는 거..

Query query = QueryParser.parse("+리바이스 +청바지", "prd_name", new CJKAnalyzer());

Searcher searcher = new IndexSearcher(dir);
searcher.search(query);

이렇게 하거나...
Analyzer analyzer = new CJKAnalyzer();
QueryParser parser = new QueryParser("prd_name",analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query query = parser.parse("리바이스 청바지");

Searcher searcher = new IndexSearcher(dir);
searcher.search(query);

이렇게..

다만 위 두개 사용방식의 차이를 알아보자는 취지...


기본적으로 search를 위해서는 Query의 인스턴스가 필요하다..
QueryParser도 Query의 인스턴스를 리턴하고 아래의 것들도 전부
Query의 인스턴스를 리턴한다.

전부 Query를 상속함.

TermQuery
Term t = new Term("prd_name", "리바이스");
Query query = new TermQuery(t);
...
searcher.search(query);

텀은 색인을 구성하는 가장 작은 단위이기 때문에 위 처럼 query를 생성하면
"리바이스" 라는 단어 그 자체가 하나의 텀이 된다.
유니크한 데이터를 검색 할 때 사용하기 편함.
(형태소 분석 필요 없는 데이터들.. ISBN등.)

표현식이 1단어로 되어 있으면 QueryParser는 TermQuery를 반환한다.

RangerQuery
Term begin, end;

begin = new Term("credate","20080310");
end = new Term("credate","20090202");

RangerQuery query = new RangerQuery(begin, end, true);
searcher.search(query);

맨 마지막 boolean 값은 양쪽 끝을 범위에 포함할지 나타내는 값. (true : 포함)

QueryParser는 [begin To end] 나  {begin To end} 와 같은 표현식으로
RangerQuery를 생성한다.

Query query = QueryParser.parse("[1/1/04 To 12/31/04]", "prd_name", new CJKAnalyzer());

PrefixQuery
시작부분에 특정 문자열 포함 문서

Term term = new Term("category", "/여성의류/치마");
PrefixQuery query = new PrefixQuery(term);
//하위 카테고리까지 검색한다..
searcher.search(query);

//여성의류/치마 카테고리만 검색한다.
searcher.search(new TermQuery(term));

QueryParser는 질의 표현식에서 *로 끝나는 텀에 대해 PrefixQuery를 생성한다.

BooleanQuery
절을 연결.
add(Query query, boolean required, boolean prohibited) 즉
query와 query를 연결.

TermQuery searchTerm = new TermQuery(new Term("prd_name","리바이스"));
RangeQuery currentSale = new RangeQuery(new Term("sale_date","200803"),
                                                                 new Term("sale_date","200805"),
                                                                 true);

BooleanQuery currentSaleSearch = new BooleanQuery();
currentSaleSearch.add(searchTerm,true,false);
currentSaleSearch.add(currentSale,true,false);

searcher.search(currentSaleSearch);

두번째 인자가 true 이면 AND
세번째 인자는 제한.

OR 질의 하려면 둘 다 false로 줘야함.

QueryParser는 다수의 텀이 사용되면 BooleanQuery를 생성한다.

WildcardQuery
*와 ?
Query query = new WildcardQuery(new Term("prd_name"),"?ild*");
searcher.search(query);

QueryParser로는 와일드카드 텀의 첫번째 문자에 와일드카드 문자가 올 수 없다.
맨 뒤에 붙은 *는 PrefixQuery로 최적화 한다.


FuzzyQuery
유사텀 검색

편집거리를 이용한 검색
three와 tree의 편집 거리는 1이다. (h삭제)


구문질의에서의 거리는 일치하는 것을 찾기 위해 텀을 움직인 횟수이지만, 레벤스타인 거리는
글자의 움직임을 텀 내부에서 계산 한 것으로 차이가 있다.

fuzzy, wuzzy

Query query = new FuzzyQuery(new Term("contents", "wuzza"));

임계값을 이용해서 비슷한다고 판단되기 때문에
검색이 된다.

-> 성능상 문제가 될 수 있다고 한다..

QueryParser에서는 텀에 ~를 붙여 사용하면 FuzzyQuery로 해석한다. (PharseQuery는 ".."~)