2009년 12월 10일 목요일

색인과 검색 그리고 하이라이팅

무엇을 검색 해야 하는가에 대한 고민은

무엇을 색인해야 하는가로 이어진다.

색인 할 그 무언가가 정해진다면,

다시 어떻게 그 검색 결과를 하이라이팅 해서 보여 줄 것인가로 귀결된다.

참 아이러니 한 이야기다.

 

게시판의 글들을 색인하는 것을 예로 들어보자.

우리는 수 많은 게시글들을 검색 대상으로 하였기에,

다양한 성향의 유저들이 쓴 글을 색인엔진에 밀어 넣어야만 했다.

 

서로 다른 옵션과 코드들을 가진 에디터가 뱉어내는

게시글들로부터 양질의 색인 데이터를 뽑아내는것이 목표였다.

또한 검색된 결과에 게시글들이 가지고 있던 혹은 악의적으로 입력된 내용이

결과 페이지의 레이아웃을 망치거나 사이트의 보안 요소를 헤쳐서는 안되었다.

에디터가 escapeHTML을 수행하는지 아닌지, 에디터에 html 태그를 허용하거나 embed,object를 허용 했는지의 여부에 따라 색인시 준비해야 할 전처리기의 명세는 달라지게 되지만,

너무 많은 전처리 작업을 수행하면 유지보수 비용이 높게 발생하거나,

한정된 시스템에 부담을 주거나 또는 신규 작성된 컨텐츠가 색인에 반영되기까지의

시간 차가 커지는 원인이 되었다.

마지막으로 양질의 검색 결과에 HTML태그와 CSS를 이용한 하이라이팅 기능이

가능해야 했으므로, HTML 태그를 무조건 제거 할 수는 없는 상황이었다.

 

무작정 달려들었다간 수만건의 데이터를 쓸모없게 만들거나,

테스트 시간만도 상당한 작업을 계속 반복하는 시행착오를 겪을 판이었다.

 

차 한잔 마실 시간이 흘렀을까?

APACHE COMMONS LANG 패키지에 포함된 StringEscapeUtils 객체가 퍼뜩 떠올랐다.

내가 색인해야 할 원본 데이터가 결과를 출력 할 HTML 페이지의 내용을 가짐으로 해서

문제가 발생한다면, 헌데, 그 내용이 HTML ESCAPE 유무의 차가 있다면,

전처리기에서 색인 할 데이터를 HTML ESCAPE 처리하여 StringUtils에

HTML REMOVE REGEXPRESSION을 사용하여 관계되는 태그를 모두 다(거의 다) 제거하면 어떨까 하는 생각이었다.

그 다음은, 그렇게 걸러진 게시글들안에 어쩔 수 없이 남아있는 새로운 태그들에 대한 처리( <!-- --> 나 < >, OBJECT, Embed 와 같은 것들 이 문제가 되었지만)를 하고 색인 파일을 만들어낸다.

그 뒤,  검색서버가 색인파일로부터 검색한 결과를 추출해내면, 하이라이팅 작업을 더해 결과를 만들어 내도록 구현하면 되었다.

[code java] //데이터베이스로부터 가져온 게시물의 정보를 담은 ArrayList<String[]> 객체 arr_indexdata           int counter=0;
     for(String[] arr_string: arr_indexdata){
      doc[counter]=new Document();
       //필드 정보를 바탕으로 문서를 작성한다.
      for(int j = 0 ; j < arr_fieldinfo.size();j++){
       //html escape로 일괄 변환후 html 태그를 제거한 내용을 저장
       doc[counter].add(new Field(arr_fieldinfo.get(j).getName()
          ,StringEscapeUtils.escapeHtml(arr_string[j]).replaceAll("(?:<!--.*?(?:--.*?--\\s*)*.*?-->)|(?:<(?:[^>'\"]*|\".*?\"|'.*?')+>)","")
          ,arr_fieldinfo.get(j).getStoretype()
          ,arr_fieldinfo.get(j).getIndextype()));
      }
      counter++;
     }
     arr_indexdata.clear();
     arr_indexdata = null; [/code]

 

 

댓글 없음:

댓글 쓰기