본문 바로가기

Lucene

Lucene 3.0 TokenStream. 그리고 Attribute. 예전에 만들었던 한글 명사 추출 Analyzer를 공개하려고 하다가 그 Analyzer의 core 버전이 2.4.0 base여서 이것을 최신 루씬 버전인 3.0으로 컨버팅 하려고 했는데... 바뀐게 한두가지가 아니라서.. 일단 바뀐 부분부터 공부를 해야겠다 싶었다. -_-; 제일 당황스러운 부분이... TokenStream.next(Token token) 메서드가 사라진 것이었다. -_-; 이 부분이 TokenStream.incrementToken() 메서드를 대체가 되었는데 이건 조만간 다시 포스팅 하기로 하고.. 일단, 기존에 사용되던 Token이란 클래스가 남아있기는 한데.. 대부분 Attribute 클래스에 기초한 놈들로 변경이 된 것 같다. 예전에 하나의 String에서 Analyzer로 분석 .. 더보기
Lucene CustomScoreQuerySample #2 - 응용편 - 우선 이 포스트에 나오는 sample 소스는 http://blog.mono-koubou.net/wp-content/uploads/2008/01/valuesourcequerysample.txt 의 소스를 살짝 수정한 소스 입니다. 앞선 포스트에서는 루씬의 CustomScoreQuery 기초적인 사용법을 보았습니다. 이번에는 이 CustomeScoreQuery를 이용해서 조금 응용을 해보겠습니다. 아래 이미지를 봐주세요. 바로 집을 기준으로 거리가 5이내에 있는 스시 집을 찾아보도록 하겠습니다. 일단, 위와 같은 결과를 얻으려면 일단 스시인 집들을 찾고 그 안에서 각 좌표를 통해 거리를 계산해야 할 것 입니다. 거리를 구하는 공식은.. 피타고라스의 정리를 이용하면 아래와 같이 구해집니다. (x'-x)^2 +.. 더보기
Lucene CustomScoreQuerySample #1 우선 아래의 소스는 http://blog.mono-koubou.net/wp-content/uploads/2008/01/valuesourcequerysample.txt 이 소스를 참고하여 좀 더 쉬운 내용으로 재구성 했음을 알려드립니다. 짐승님을 통해 알게 된 CustomScoreQuery. 이게 보면 볼 수록 매력적이다. 내일 공휴일이기도 하고.. 이런거 한번 삘 받았을 때 좀 파보고 싶어서 위 링크의 소스를 보고 간단하게 이것 저것 테스트를 해보기 위한 소스를 만들어 보았다. 2개의 필드를 가진 데이터를 RamDirectory에 색인 해 놓고 검색 테스트를 하면서 score가 어떻게 변하는지 보았다. 위 예제에서는 ValueSource등을 거리 계산 값으로 계산하기 위한 Inner Class들이 몇 개.. 더보기
Lucene 3.0 그리고 CustomScoreQuery. http://softwaregeeks.org/blog/271 트랙백을 남겨주신 짐승님의 글을 보고 ... ^^ 항상 검색 엔진의 인덱스 파일의 용량이 대용량으로 가면서 문제 되는 것이 정렬 문제 였다. 그러던 중 짐승님이 남겨주신 트랙백의 글을 보고 정신이 탁 트여지는 것을 느꼈다. 예전에도 루씬의 DocScore를 가중치나 계산 공식 변경등을 통해 수정 할 수 있다는 것은 알았었는데 그 score자체가 정렬과 연관이 지어지지를 않고 있었다. 그런데 짐승님의 (아 이거 어감이 정말..-_-;;;) 글 http://softwaregeeks.org/blog/271 을 보고나니 뭔가 탁~~~ 하고 깨이는 느낌.. 나는 왜 저렇게 생각의 전환이 안 되는거지... -.-; 안그래도 회사에서 로그 분석을 간단하게 .. 더보기
[루씬] 동의어 필터 제가 만들어서 사용하던 Analyzer에서 쓰던 동의어 필터입니다. 쇼핑몰을 염두해두고 작업했던 분석기라서 동의어 처리가 필요했는데요 아이디어 및 기초 소스는 루씬인액션 책에서 얻었고.. 그 소스를 좀 수정해서 만들었습니다. 책에는 영어의 동의어를 어디 사이트에서 가져올 수 있다고 되어 있었는데 한글은 그런 사이트를 찾을 수가 없어서 생각해보다가 Analyzer의 최초 인스턴스 생성시 RamDirectory를 사용해서 동의어를 색인해 놓고 Token에 대한 동의어를 뽑아주는 방식을 사용했습니다. 동의어사전의 형식은 그냥 오라클,oracle 노트북,notebook,note피씨 식으로 한 row에 ,로 구분해서 넣어주시면 되고 사전명은 디폴트로 synonym.txt로 설정되어 있습니다. 위치는 webappl.. 더보기
루씬 2.9 많이 바뀌었네요...;;;; 오랜만에 개인적으로 뭘 만드느라고 다시 루씬을 만졌는데.. 2.9가 릴리즈 되어 있어서 냉큼 받아서 사용하려고 해보니 많이 바뀌었네요 --;;;; 3.0으로 넘어가기 위한 준비인가.... 검색 하려면 아래와 같이.. SortField sf = new SortField("count", SortField.LONG, true); Sort sort = new Sort(sf); Directory dir = FSDirectory.open(new File("d:/index")); IndexSearcher searcher = new IndexSearcher(IndexReader.open(dir, true)); TopFieldCollector collector = TopFieldCollector.create(sort, .. 더보기
IndexReader.isCurrent() IndexReader에 대해서.. 색인이 되어 있는 인덱스 파일이 있습니다. 이것을 IndexReader를 사용해서 IndexSeacher를 생성하겠습니다. 이때 reader.isCurrent()의 값은 true입니다. 이 상태에서 같은 인덱스 파일이 있는 디렉토리에 다시 색인을 해보겠습니다. 위 메서드를 이용해서 다시 색인하고 reader.isCureent()를 다시 확인해보면 결과는 false가 나옵니다. 새롭게 작성된 인덱스 파일이 존재하기 때문입니다. IndexWriter를 생성 할 때 생성자에 들어가는 3번째 인자가 인덱스 파일을 지우고 새로 생성하느냐 아니면 추가되는 document를 append 하느냐를 나타냅니다. (true면 새로 생성) IndexWriter writer = new Ind.. 더보기
[lucene] IndexReader reopen. 루씬에서 IndexReader와 IndexSearcher 그리고 IndexWriter는 보통 하나의 인덱스 파일을 바라보며 작업을 합니다. 그리고 서로가 인덱스파일의 상태를 공유하지 못 합니다. 기본적으로 읽기/쓰기 등에 대해서 한꺼번에 작업이 일어나지 못 하도록 Lock 기능을 보유하고 있긴 하지만 IndexWriter가 인덱스 파일에 Document를 추가하고 commit을 시켰다고 해서 그 내용이 바로 IndexReader나 IndexSearcher에게 영향을 미치지 못 합니다. 하지만 검색 서비스를 위해서는 항상 일명 전체색인만으로 서비스를 제공할 수 있는 경우는 거의 없습니다. 증분색인 혹은 실시간 색인을 통해 일정 주기마다 변경되는 사항을 인덱스 파일에 반영 할 필요가 있습니다. 이것은 Ind.. 더보기
lucene tfldf weights i used lucene-2.4.0 to get tf-idf. i'm not sure if the newer versions have direct methods to get tf-idfs as well. this is lengthy but might help. // Get Term Enum that contains all the terms in the index using FilterIndexReader TermEnum e = freader.terms(); // find total number of docs int noOfDocs = freader.numDocs(); // Get TermDocs Enum TermDocs td = freader.termDocs(); // seeking through all.. 더보기
루씬 Score. 루씬 2.4로 넘어오면서 Hits 객체로 검색 결과를 받아오던 방식이 TopDocCollector를 이용하는 방식으로 변경되면서 Score를 조회했을때 그 Score가 이전 버전과는 다르게 나왔었습니다. 예전에는 0 ~ 1사이로 정규화가 되었었는데 지금은 아니더라구요. 왜 그러지 궁금해 하면서도 그냥 넘어가고 있었는데 마침 메일링 리스트에 관련된 내용이 올라왔네요. 일단, 현재 2.4 버젼에서 검색 후 검색된 Document의 Score를 얻는 방법은 아래와 같습니다. TopDocCollector collector = new TopDocCollector(10); searcher.search(query, collector); ScoreDocs[] hits= collector.topDocs().scoreDo.. 더보기