사이트 내 전체검색
[DBMS] MySQL FULLTEXT을 이용한 형태소 분석없는 한글검색 방법
로빈아빠
https://cmd.kr/server/1024 URL이 복사되었습니다.

본문

이 내용은 MySQL의 검색성능 향상을 고민하시는 초보분들에게 도움이 되었으면 합니다.
600만개 이상의 클럽박스 파일을 검색하는 http://boxfile.co.kr 을 만들면서 적용한 방법입니다.

MySQL의 검색속도에 대해서 초보시절에는 얼마 안되는데 DB량으로 인해 생각해 볼 기회가 없었던것 같네요.

조금 경력이 늘어난만큼 다루는 DB량도 규모가 있어지기 시작하면서 MySQL뿐 아니라 다른 DBMS에서도 본문 검색에 있어서 기본적인 한계란 것이 존재하는 것을 알게 되었습니다.

결국 검색 속도를 올리는 방법으로 FullText, 역인덱스 기능등이 있으나
가장 단순한 방법이 FullText검색이라 생각하게 되면서 한글검색 능력을 향상시킬 수 있는 방법을 찾던 중

한글형태소 분석이라는 새로운 분야까지 공부를 하게되더군요
하지만 형태소 분석을 완전히 내 것으로 만들기에는 능력의 한계가 있었고
결국 단순하면서도 검색이 잘되는 방법을 찾은 것이 "한글 쪼개기"더군요

우선 MySQL에서 한글 검색이 되려면 UTF-8 로 저장이 되어야 합니다.
EUC-KR환경에서 MySQL에 접속하여 DB를 사용하기 위해서는
SET NAMES EUCKR 이라는 쿼리 한방 날리고 나서 작업을 한다면
PHP페이지 안에서 UTF-8로 변환해서 작업 할 필요는 없습니다.

한글 쪼개기는 가장 단순한 방법으로
$STR = "한글검색 속도를 향상 시키는 방법"
위 $STR의 내용을 FULL-TEXT검색에서 사용하기 위하여 단순한 쪼개기를 합니다.
그 결과는 "한글검색 한글 글검 검색 속도를 속도 도를 향상 시키는 시키 키는 방법" 단어의 수가 급격하게 늘어나지만  array_unique() 합수를 사용하여 중복 단어를 제외 시킬 수 있습니다.

이렇게 한글 쪼개는 이유는 FULLTEXT는 Stopword에 의해서 단어가 나뉘고 단어의 첫 시작 즉 Like '검색어%' 와 같은 검색을 통해서 사용 할 수 있기때문입니다.

create table searchdata(
......
hankey text,
fulltext(hankey),
..)

검색어 : 형태소
$querymake = "(형태 + 태소)";

검색어 : 형태소 + 한글검색
$querymake = "(형태 + 태소) + (한글 + 글검 + 검색)";

select * from  searchdata where MATCH (hankey) AGAINST ('$querymake' IN BOOLEAN MODE)


좀더 자세한 내용은 http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html



<?
$str = "한글검색 속도를 향상 시키는 방법";

//논워드
$str1 = preg_replace("/\W/"," ",$str);
$str1 = preg_replace("([\s]+)"," ",$str1);

//아스키값을통한 정규표현 가
$str2 = preg_replace('/([\000-\176])/'," ",$str);
$str2 = preg_replace("([\s]+)"," ",$str2);

$eenarr = explode(" ",$str1);
$hanarr = explode(" ",$str2);

$enstr = "";
foreach($eenarr as $value){
    $value = eregi_replace("([a-z]+)([0-9]+)$","",$value);
    $value = eregi_replace("^([0-9])([0-9abcdefx]+)$","",$value);
    $value = eregi_replace("^([abcdef])([0-9])([0-9abcdefx]+)$","",$value);            
    $value = eregi_replace("^([abcdef])([abcdef])([0-9])(.*)$","",$value);            
    $value = eregi_replace("^([a-z]+)([0-9]+)([a-z]+)([0-9]+)(.*)$","",$value);
    $value = eregi_replace("^(.*)(aaa|bbb|ccc|ddd|eee|fff|ggg|hhh|iii|jjj|kkk|lll|mmm|nnn|ooo|ppp|qqq|rrr|sss|ttt|uuu|vvv|www|xxx|yyy|zzz)(.*)$","",$value);
    $enstr .= $value. " " ;
}

foreach($hanarr as $key=>$value){
    $value = ishanishan($value);
    $strlen = strlen($value);
    if($strlen  >=  4 ){
        $makekey = hankeycheck($value);
        $newkey[] = $value;
        for($i=0;$i<count($makekey);$i++){
            $newkey[] = $makekey[$i];
        }
    }
}


$laststr = implode(" ",array_unique($newkey)).  " $enstr ";

echo $laststr;
//한글검색 한글 글검 검색 속도를 속도 도를 시키는 시키 키는


function ishanishan($str){
    $for = strlen($str) / 2;
    for($i=0;$i<$for;$i++){
        $s = $i*2;
        $char = substr($str,$s,2);
        $newstr .= ($char >= '가' && $char <= '힝')? $char : ""  ;
    }
    return $newstr ;
}

function hankeycheck($str){
    $for = strlen($str) / 2;
    for($i=0;$i<$for-1;$i++){
        $arr[] = substr($str,$i*2,4);
    }
    return $arr;
}
?>
  License
본 게시물은 GPL을 따릅니다. [ GPL 안내 ]

댓글목록

등록된 댓글이 없습니다.

1,139 (22/23P)

Search

Copyright © Cmd 명령어 3.128.31.227