Lucene 인 스 턴 스 튜 토리 얼 (3) 의 조작 색인

오리지널 작품 은 전 재 를 허용 하고 전 재 를 할 때 반드시 하이퍼링크 형식 으로 글 의 출처, 작가 정보 와 본인 성명 을 표시 해 야 합 니 다.그렇지 않 으 면 법 적 책임 을 추궁 할 것 이다.
저자: 영원의☆ 주소:http://blog.csdn.net/chenghui0317/article/details/10366255
머리말
       루 셀 을 사용 하여 색인 을 디스크 에 기록 하 는 방법 을 간단하게 소개 하고 IKAnalyzer 중국어 단어 기 동작 색인 과 검색 색인 파일, 주 소 를 제공 합 니 다.http://blog.csdn.net/chenghui0317/article/details/10281311
       프로젝트 실전 에서 이것 은 비교적 까다 로 운 문 제 를 완전히 해결 할 수 없다. 예 를 들 어:
       1. 이전에 색인 을 어떻게 쓰 는 지 소 개 했 지만 색인 을 삭제 하고 색인 을 수정 하 는 작업 을 제공 하지 않 았 기 때문에 색인 파일 의 누적 은 더러 운 데이터 나 데이터 중복 이 발생 할 수 있 습 니 다.
2. 루 센 실전 사용
1. Lucene 작업 색인 파일 사용
실현 의 사고방식 은 다음 과 같다.   <1 > 원래 사 용 했 던 IndexReader 작업 색인 은 편리 하지 않 습 니 다. IndexReader. Close () 를 실행 할 때 만 삭제 작업 이 실 행 됩 니 다. 또한 이러한 방식 의 IndexReader 인 스 턴 스 방법 은 만 료 된 방법 으로 바 뀌 었 기 때문에 이러한 방식 은 바람 직 하지 않 습 니 다.
   <2 > 색인 을 쓸 때 IndexWriter 색인 기록 기 를 사용 한 이상 삭제 와 수정 도 마찬가지 로 사용 합 니 다.   <3 > 색인 을 쓰 는 실현 방식: 이전 과 같이 IndexWriter 기록 기 를 사용 하여 addDocument () 를 호출 하면 됩 니 다.
   <4 > 색인 삭제 실현 방식: 색인 파일 이 존재 하 는 지 판단 해 야 합 니 다. IndexWriter 기록 기 를 사용 하여 deleteDocument () 을 호출 하면 됩 니 다.
   <5 > 색인 을 수정 하 는 실현 방식: IndexWriter 기록 기 가 updateDocument () 를 직접 제공 하지 않 았 기 때문에 수정 할 색인 을 삭제 한 다음 에 수 정 된 색인 을 기록 하면 효과 가 같 습 니 다.
   <6 > 마지막 으로 IndexWriter 를 닫 는 것 을 잊 지 마 세 요. 그렇지 않 으 면 자원 이 계속 점용 되 고 메모리 비용 을 낭비 합 니 다.
구체 적 인 코드 는 다음 과 같다.
package com.lucene.test;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.lucene.entity.Article;

/**
 * Lucene           
 * @author Administrator
 *
 */
public class OperateIndexDemo {
    
    public static final String INDEX_DIR_PATH = "indexDir";
    /*                                    ,            */
    private Analyzer analyzer = null;
    //       
    private File indexFile = null;
    //    ,             ,         
    private Directory directory = null;
    //  IndexWriter     
    IndexWriterConfig indexWriterConfig = null;
    
    SimpleDateFormat simpleDateFormat = null;
    
    /**
     *      
     * @throws IOException 
     */
    public void init() throws IOException{
        analyzer = new IKAnalyzer(true);
        indexFile = new File(INDEX_DIR_PATH);
        directory = new SimpleFSDirectory(indexFile);
        
        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("*****************     **********************");
    }
    
    /**
     *  article          document  ,          
     * @param article
     * @return
     */
    public Document createDocument(Article article){
        Document document = new Document();
        document.add(new Field("id", article.getId().toString(),Field.Store.YES, Field.Index.NOT_ANALYZED));
        document.add(new Field("title", article.getTitle().toString(),Field.Store.YES, Field.Index.ANALYZED));
        document.add(new Field("content", article.getContent().toString(),Field.Store.YES, Field.Index.ANALYZED));
        
        return document;
    }
    
    /**
     *             
     * @return
     */
    public String getDate(){
        return simpleDateFormat.format(new Date());
    }

    /**
     *                  ,                    
     * @throws IOException 
     * @throws CorruptIndexException 
     */
    public void openIndexFile() throws CorruptIndexException, IOException{
        System.out.println("*****************      **********************");
        IndexReader indexReader = IndexReader.open(directory);
        int docLength = indexReader.maxDoc();
        for (int i = 0; i < docLength; i++) {
            Document doc = indexReader.document(i);
            Article article = new Article();
            if (doc.get("id") == null) {
                System.out.println("id  ");
            } else {
                article.setId(Integer.parseInt(doc.get("id")));
                article.setTitle(doc.get("title"));
                article.setContent(doc.get("content"));
            }
            System.out.println(article);
        }
        System.out.println("*****************      **********************
");     }          /**      *      * @param article      * @throws IOException      * @throws LockObtainFailedException      * @throws CorruptIndexException      */     public void createIndex(Article article) throws CorruptIndexException, LockObtainFailedException, IOException{         indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);         IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);         indexWriter.addDocument(createDocument(article));                  indexWriter.close();         System.out.println("[ " + getDate() + " ] Lucene [" + indexFile.getAbsolutePath() + "] 。");     }          /**      * id      * @param contentId      * @throws IOException      * @throws ParseException      */     public void deleteIndex(String contentId) throws IOException, ParseException{         // , true , false         if(IndexReader.indexExists(directory)){             indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);             IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);             // term id , contentId , ,             indexWriter.deleteDocuments(new Term("id",contentId));             /*             QueryParser queryParser = new QueryParser(Version.LUCENE_36, "id", analyzer);             Query query = queryParser.parse(contentId);             indexWriter.deleteDocuments(query);             */             indexWriter.close();             System.out.println("[ " + getDate() + " ] Lucene [" + indexFile.getAbsolutePath() + "] 。");         }else{             throw new IOException("[ " + getDate() + " ] Lucene , " + indexFile.getAbsolutePath() + " 。" );         }     }          /**      * , , ,      * @param article      * @throws IOException      * @throws ParseException      */     public void updateIndex(Article article) throws IOException, ParseException{         deleteIndex(article.getId().toString());         createIndex(article);     }     /**      * ,      *      * @throws IOException      */     public void destory() throws IOException{         analyzer.close();         directory.close();         System.out.println("***************** **********************");     }          public static void main(String[] args) {         OperateIndexDemo luceneInstance = new OperateIndexDemo();         try {             luceneInstance.init();//                          Article article = new Article(1," "," 。 。。。。。。。。。。");             luceneInstance.createIndex(article);             luceneInstance.openIndexFile();                          luceneInstance.deleteIndex("1");             luceneInstance.openIndexFile();                          //article = new Article(1," "," ");             //luceneInstance.updateIndex(article);             //luceneInstance.openIndexFile();         } catch (IOException e) {             e.printStackTrace();         } catch (ParseException e) {             e.printStackTrace();         }finally{             try {                 luceneInstance.destory();//             } catch (IOException e) {                 e.printStackTrace();             }         }     } }

위의 코드 는 재 구성 과 최적화 를 했 고 모든 방법 은 한 가지 일 만 하 며 분업 이 매우 명확 하 다.
    init()  ------> 전역 변 수 를 예화 하 는 데 사용 합 니 다.
    createDocument(Article article)  ------> article 대상 의 속성 을 모두 document 대상 으로 밀봉 하고 재 구성 한 후에 색인 을 만 들 수 있 습 니 다.
    openIndexFile()  ------> 색인 파일 을 조작 한 후의 효 과 를 사실대로 반영 하기 위해 매번 조작 후 색인 디 렉 터 리 에 있 는 모든 색인 내용 을 조회 합 니 다.
    createIndex(Article article)  ------> 디스크 에 색인 쓰기;
    deleteIndex(String contentId)  ------> 색인 파일 의 색인 삭제 에 사용 하기;
    updateIndex(Article article)  ------> 색인 파일 의 색인 수정 하기;
    destory()  ------> 자원 을 방출 하여 디 렉 터 리 연결 을 닫 는 데 사용 합 니 다.
    <1 > 우선 createDocument (Article article) 을 호출 합 니 다. 구체 적 인 효 과 는 다음 과 같 습 니 다.
Lucene 实例教程(三)之操作索引_第1张图片
알림 에 따라 색인 파일 디 렉 터 리 를 보면 색인 이 성공 적 으로 기록 되 었 음 을 나타 낸다.
그리고 설명 이 필요 한 것 은:
    1. 매번 작 동 하 는 IndexWriterConfig 의 인 스 턴 스 는 두 번 이상 사용 할 수 없습니다. 그렇지 않 으 면 다음 과 같은 오류 가 발생 합 니 다.
Exception in thread "main"org.apache.lucene.util.SetOnce$AlreadySetException: The object cannot be set twice!
그래서 실례 화 된 후에 한 번 만 사용 할 수 있 고 같은 유형의 조작 도 안 된다.
    2. 전체 응용 프로그램의 실행 주 기 는 다음 과 같다. (1) 실례 화.    (2) 초기 화;    (3) 구체 적 인 조작;    (4) 소각.   
directory 가 닫 혔 는데 도 directory 디 렉 터 리 대상 을 계속 조작 하면 다음 과 같은 오류 가 발생 합 니 다.
Exception in thread "main"org.apache.lucene.store.AlreadyClosedException: this Directory is closed
    <2 > 다음 에 deleteIndex (String contentId) 방법 을 살 펴 보 겠 습 니 다. 먼저 색인 파일 에 색인 파일 이 있 는 지 판단 하고 있 으 면 색인 디 렉 터 리 에서 해당 하 는 색인 을 찾 고 있 으 면 삭제 하 며 없 으 면 아무것도 하지 않 습 니 다.
구체 적 으로 는 색인 파일 을 색인 디 렉 터 리 에서 모두 삭제 한 다음 deleteIndex (String contentId) 방법 을 실행 할 수 있 습 니 다. 구체 적 인 효 과 는 다음 과 같 습 니 다.
Lucene 实例教程(三)之操作索引_第2张图片
그 다음 에 색인 을 다시 쓴 다음 에 추 가 된 article 의 id 를 삭제 하고 다음 과 같이 실행 합 니 다. 구체 적 인 효 과 는 다음 과 같 습 니 다.
Lucene 实例教程(三)之操作索引_第3张图片
삭제 한 후에 색인 파일 을 조회 하면 해당 하 는 기록 이 없 는 것 을 발견 하여 색인 삭제 에 성 공 했 음 을 나타 낸다.또한 삭제 할 때 존재 하지 않 는 아 이 디 를 지정 하면 루 센 이 아무것도 하지 않 는 모습 을 볼 수 있다.
또한 eclipse 의 방법 에 따라 다음 과 같이 제시 합 니 다.
Lucene 实例教程(三)之操作索引_第4张图片
이 방법 은 Term 과 Query 의 재 부팅 을 지원 하고 매개 변수 개수 에 상한 이 없 기 때문에 IndexWriter 가 제공 하 는 deleteDocuments 방법 은 하나의 색인 삭제 도 지원 하고 여러 색인 삭제 도 지원 하 며 조건 만 만족 시 키 면 됩 니 다.  
이제 indexWriter. deleteDocuments (new Term ("id", contentId) 를;설명 이 떨 어 지고 아래 설명 을 취소 하 는 코드 를 교체 한 다음 삭제 작업 을 실행 합 니 다. 구체 적 인 효 과 는 위의 것 과 같 기 때문에 색인 을 삭제 하 는 방법 은 모두 색인 을 삭제 하 는 것 을 표시 할 수 있 습 니 다.  또한 Term 의 인 스 턴 스 를 사용 하여 일반적으로 단일 색인 삭제 에 사용 되 며, Query 의 인 스 턴 스 를 사용 하여 일반적으로 단일 이상 의 색인 삭제 에 사 용 됩 니 다.
    <3 > 마지막 으로 updateIndex (Article article) 를 보 세 요. 이 방법 은 가장 간단 합 니 다. createIndex (Article article) 와 deleteIndex (String contentId) 를 직접 호출 합 니 다. 왜 IndexWriter 가 update 방법 을 제공 하지 않 았 는 지, 색인 이 색인 파일 에 기 록 된 후에 저장 구 조 를 파괴 하 는 것 을 허용 하지 않 았 기 때 문 일 수도 있 습 니 다. 데이터 시트 기록 의 수정 작업 도 마찬가지 일 수도 있 습 니 다. 먼저 삭제 하고 새로 추가 합 니 다.
이 방법 을 실행 하 는 구체 적 인 효과 도 는 다음 과 같다.
Lucene 实例教程(三)之操作索引_第5张图片
그림 에서 마지막 으로 색인 을 연 결과 색인 이 수정 되 었 음 을 보 여 줍 니 다.
OK, 색인 을 조작 하 는 기본 기능 이 모두 실현 되 었 습 니 다.     종이 위 에서 읽 으 면 결국 얕 게 느껴 져 서 이 일 을 몸소 해 야 한 다 는 것 을 절대 알 수 있다.

좋은 웹페이지 즐겨찾기