개발관련/Lucene,ElasticSearch 2015. 11. 23. 17:01

루씬은 색인과 검색 두가지로 나뉜다. 기존 색인을 검색 할 때도 쓰이지만, 특정 문장을 검증 할때도 쓰인다. 


루씬의 version은 3.6 기준으로 작성하였다. 


먼저 검색은 두가지 객체가 중요하다. IndexReader와 IndexSearcher 여기서 reader는 특정 색인의 접근을 해주는 객체이며, searcher는 그 색인을 찾고자 하는 검색 룰을 전달해주는 넘이다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
    private IndexSearcher searcher;
    private Directory dir;
    private IndexReader reader;
    private String textField;
 
    @Before    
    public void setup() throws IOException {
        textField = "text";
        dir = FSDirectory.open(new File(dirPath));
        reader = IndexReader.open(dir);
        searcher = new IndexSearcher(reader);
    }
    @After
    public void tearDown() throws IOException {
        searcher.close();
        reader.close();
    }
cs


먼저 초기 셋팅을 해준다. 기존에 만들어 놓은 index경로는 dirPath가 될 것이다. 검색 필드는 "text"로 지정한다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    private ArrayList<Document> dumpHits(IndexSearcher searcher, TopDocs hits,
            String fieldName) throws IOException {
        ArrayList<Document> docList = null;
        if (hits.totalHits == 0) {
            return null;
        }
        docList = new ArrayList<Document>();
        for (ScoreDoc match : hits.scoreDocs) {
            Document doc = searcher.doc(match.doc);
        }
        return docList;
    }
 
    public void searchIndex(String searchString, String field) throws ParseException, IOException  {
        System.out.println("\nSearching for '" + searchString + "' using QueryParser");
 
        QueryParser queryParser = new QueryParser(Version.LUCENE_36, field, new StandardAnalyzer(Version.LUCENE_36));
        Query query = queryParser.parse(searchString);
        System.out.println("Type of query: " + query.getClass().getSimpleName());
        TopDocs hits = searcher.search(query, searcher.maxDoc());
        dumpHits(searcher, hits, field);
 
    }
 
    @Test
    public void testHtmlBasicSearchData() {
        String andWordSearch = "cross";
        
        if (andWordSearch != null && andWordSearch != "") {
                try {
                    searchIndex(andWordSearch, textField);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
 
        }
        
    }
cs


가장 기본인 검색이다... (개인적으로 이방법은 안쓴다.. =_=; 찾는것도 힘드네 ㅋㅋ)  

여기서 중요한 함수는 searchIndex라는 함수다.  


중요한 객체는 총 3가지 , QueryParser와 Query, TopDocs 이 객체만 알면 Lucene을 가지고 분석을 자유롭게 할 수 있을 것이다. 먼저 한개씩 설명하자면,  


1. QueryParser : 입력한 Query문을 Lucene이 알아먹을 수 있는 Query로 변환한다. 쉽게 말하자면 당신이 넣은 쿼리를 선택한 분석기에 맞게 쿼리 객체 형태로 반환한다. 

2. Query : QueryParser로 변환된 쿼리 객체를 searcher 객체로 전달한다. (Query의 종류는 상당히 많으며, 최상위 객체가 Query이다. 종류는 TermQuery, BooleanQuery, Fuzzy, WildCard 등등 있다)

3. TocDocs : 검색된 결과를 보여준다. 


위의 결과를 돌려보면 

1
2
3
4
5
Searching for 'cross' using QueryParser
Type of query: TermQuery
 
 
 
cs


이런 형태가 나오고 dubugging모드로 Query를 보면 text:cross 란 쿼리로 변환이 될것이다. 


아마도 default Query는 TermQuery 이며, 객체를 통해 Lucene이 알아먹을 수 있는 형태의 쿼리로 변환 되는 듯 보인다. 


이후 좀더 복잡한 쿼리에 대해 알아보겠다. 



posted by 제스트
: