lucene IndexReader reOpen에 대한 철저한 연구

Lucene의 reopen에 문제가 있다고 생각했는데 오늘 특별히 연구를 했습니다. 그리고 전체 IndexReader의 구조 체계인 IndexReader는 하나의 체계입니다. 그는 Search의 핵심 io 중 하나입니다.

org.apache.lucene.index


Class IndexReader

java.lang.Object   org.apache.lucene.index.IndexReader 

Direct Known Subclasses:
FilterIndexReader,
MultiReader,
ParallelReader
먼저 IndexReader 아래의 클래스 체계를 살펴보겠습니다. 저희가 평소에 사용하는 세 가지 파생: FilterIndexReader MultiReader ParallelReader
다음은 제가 실수를 한 리오픈을 보겠습니다.
public IndexReader reopen()                    throws CorruptIndexException,                           IOException
이전에 왜 내가 틀렸는지, 나는 이 방법이 자성하는 줄 알았다.그래서 제가 어떻게 썼죠?
iSearch.getIndexReader().reopen();
이렇게 하면 리오픈이 된다고 착각했는데 결과는 항상 업데이트가 없다는 고소를 받아서 계속 업데이트에 문제가 있다고 생각했어요. 사실은 제 용법의 문제예요. 그래야 돼요.
if (iSearch != null) {
//새로 수정된reopen 방법
try {
IndexReader irOld = this.reOpen(iSearch);
//isearchMap.remove(searchBean.getIsearchName());
isearchMap.put(searchBean.getIsearchName(),
new IndexSearcher(irOld));
} catch (Exception e) {
e.printStackTrace();
} finally {
//원래 iSearch를 닫아야 합니다.
iSearch.close();
iSearch = null;
logger.info(">>>>>>>>>>>>>one search has been reopen:"
+ searchBean.getIsearchName());
}
}
위에는 프로그램에서 캡처한 것이니 뜻을 보면 된다.
그러나 나중에 이것이 옳지 않다는 것을 발견했다. 원본 코드의 설명을 보면 다음과 같다.
If the index has not changed since this instance was (re)opened, then this
* call is a NOOP and returns this instance. Otherwise, a new instance is
* returned. The old instance is not closed and remains usable.
만약 변화가 없다면, 그는 null로 돌아갈 것이다. 그러면 어쩔 수 없이 판단해야 하기 때문에 코드는 다음과 같다.
if (iSearch != null) {
//새로 수정된reopen 방법
try {
IndexReader irOld = reOpen(iSearch);
if (irOld != null) {
//isearchMap.remove(searchBean.getIsearchName());
isearchMap.put(searchBean.getIsearchName(),
new IndexSearcher(irOld));
//원래 iSearch를 닫아야 합니다.
iSearch.close();
iSearch = null;
}
} catch (Exception e) {
logger.error(e);
} finally {
logger.info(">>>>>>>>>>>>>one search has been reopen:"
+ searchBean.getIsearchName());
}
}
이렇게 하면 색인이 변하지 않고 더 많은 io 소모가 발생하지 않을 수 있다. 그러면 우리는 Reopn의 실질을 이해할 수 있다.
우선lastmodify 시간을 판단하고 업데이트되면 new는 IndexReader입니다. 그렇지 않으면null로 돌아가고 조작 방법은 사용자에게 던져집니다.그래서 공식적인 이른바 Reopen이 소모를 줄일 수 있다는 말은 정확하지 않다. 이것은 바뀔 때 다시 연결하는 것일 뿐이다. 그러나 이 공식 문서가 말한 업데이트 부분만 업데이트하는 것은 크게 다르다. 지금은 선택적으로 io를 낮출 뿐이다. 그러나 매번 탐색할 때 색인이 바뀌면 의미가 없어진다. 이런 맛은 색인 추적이 더욱 빈번해지고 프로그램이 지나치게 관여할 필요가 없다는 것이다.
그러나 현재 이 방법은 성숙하지 않다. 적어도 나는 그렇게 많은 세부 사항을 개발자에게 던져주는 것이 아니라 더 바보적이어야 한다고 생각한다.
자, 리오픈이라는 신흥 방법은 철저히 이해한 셈이다. 허풍을 떠는 것처럼 보이는 새로운 물건인지, 낡은 병에 새 술을 담는 건지, 허허......
마지막으로 코드를 보완합니다.
if (iSearch != null) {
//새로 수정된reopen 방법
    Boolean isNew = false;
    try {
     IndexReader irOld = reOpen(iSearch);
     if (irOld != null) {
      isNew = true;
      //isearchMap.remove(searchBean.getIsearchName());
      isearchMap.put(searchBean.getIsearchName(),
        new IndexSearcher(irOld));
     }
    } catch (Exception e) {
     logger.error(e);
    } finally {
     if (isNew) {
//자원을 닫지 않도록 보증합니다. 그렇지 않으면 연결을 한 번 더 세어 기계 io를 끊을 수 있습니다
      iSearch.close();
      iSearch = null;
     }
     logger.info(">>>>>>>>>>>>>one search has been reopen:"
       + searchBean.getIsearchName());
    }

좋은 웹페이지 즐겨찾기