짬 나는대로 회원 검색을 위한 모듈을 만들고 있습니다.

이것은 그동안 제 고민의 흔적ㅋ

  • 모듈 이름 고민 : https://xetown.com/qna/1031132
  • DB 생성 고민 : https://xetown.com/qna/1032338
  • 트리거 고민 : https://xetown.com/board/1034216

 

그렇지만, 아무래도 모듈 개발 습작이 될 듯해요;;;

서버 부하를 최소화한다는 게 어마어마하게 힘든 일이란 걸 실감하고 있습니다.

  1. 검색창 포커스 -> DB 쿼리 요청 -> 결과값을 로컬저장소에 저장 -> 검색어 입력에 따라 로컬저장소의 결과값을 출력
    => 그렇지만 회원수가 1천명 넘는 규모가 된다든가 하면 클라이언트단에서 로컬저장소의 결과값을 자체 핸들링한다는 게 속도 저하를 가져옵니다ㅠ
  2. 검색어 입력 -> (약간의 시간차를 두고) 실시간 DB 쿼리 요청 -> list_count에 따라 결과값을 출력
    => 이용자들이 회원 검색 서비스를 많이 이용하면 할수록 서버 부하가 발생할 수 있고, 이 경우에도 회원들이 많으면 아무래도;;;

결국, 어떤 식으로든 범용 모듈은 될 수 없겠다는 판단이 듭니다.

(저는 이런 걸 꼭 해봐야 알아요ㅋㅋㅋ큐ㅠㅠㅠ)

 

그래도 기왕에 만드는 거 쓰레기통에 버리더라도 제대로 만들어봐야겠다는 생각이 듭니다.

일단은 위의 2번 방식으로요. 2018년 8월 18일 12시 18분 현재 https://bit.ly/2nMCn09

 

앞으로는 검색결과를 유사도 순으로 뿌려주는 걸 해볼까 해요.

구글링해보니 인덱싱 어쩌구 검색엔진 저쩌구 하는데, 엘라스틱이니 그런 거는 제가 감히 넘볼 수 없는 영역 같구요.

그냥 php단에서 해볼 수 없을까 고민 중입니다.ㅎㅎ

 

php 자체적으로 이런 함수도 있는 것 같구요.

  • similar_text : http://php.net/manual/en/function.similar-text.php
  • levenshtein : http://php.net/manual/en/function.levenshtein.php

뭐 꼭 그게 아니더라도 알고리즘 비스무리한 것도 있는 것 같습니다.

  • StrikeAMatch 알고리즘 : https://code.i-harness.com/ko/q/9f765#answer7

물론 속도가 관건이겠네요 으흐흐흐

윤삼

profile
아무래도 중급 초반 수준의 코딩 오타쿠인 것 같습니다.
  • profile
    이런 것도 발견
    https://gist.github.com/TechyTimo/1e888896844adc7c5e1c5af15a98b1a0
  • ?
    PHP에서 비교하면, SQL쿼리 결과로 받은 데이터 내에서만 정렬이 되지 않나요?
  • ? profile
    어ㅜ 그러네요ㅜㅜ
    DB에서 모든 데이터를 다 가져오지 않는 이상;;
    하아....
  • ? profile
    https://stackoverflow.com/questions/15026244/mysql-order-by-relevance
    LIKE 대신 MATCH AGAINST 라는 걸 쓴다는 것 같은데
    이런 쪽으론 좀 시도해볼 만한 건가요?
  • profile ?
    저도 궁금해서 여쭤본거라... 잘 모르겠습니다.
  • ? profile
    암튼 지적해주신 부분이 맞는 말씀 같아요. DB 자체에서 유사도순 정렬할 방법을 찾아봐야겠어요.
    말씀 안 해주셨으면 완전 헛수고할 뻔했어요 ^^;;
  • profile

    이런 게 있군요. 기록을 위해 남겨둡니다.
    http://jason-heo.github.io/mysql/2014/03/05/sort-string-after-search2.html

    그래서 다음과 같이 해결했습니다.

     

    $db_info = Context::getDBInfo();
    $prefix = $db_info->master_db['db_table_prefix'];
    $DB = DB::getInstance();
    $query = $DB->_query("SELECT *, 
        (LENGTH(". $search_target .") - LENGTH((REPLACE(". $search_target .", '". $search_keyword ."', '')))) / LENGTH('". $search_keyword ."') AS score, 
        INSTR(". $search_target .",'". $search_keyword ."') AS strpos 
        FROM ". $prefix ."user 
        WHERE ". $search_target ." LIKE '%". $search_keyword ."%' 
        ORDER BY score DESC, strpos ASC, ". $search_target ." ASC 
        LIMIT 0, 5");
    $result = $DB->_fetch($query);
    if ( !is_array($result) )
    {
        $result = array($result);
    }

     

    이렇게 하면 1) 검색어가 데이터에 몇 개 있는지(내림차순), 2) 검색어가 데이터 문자열 어느 위치에 있는지(오름차순), 3) 데이터 오름차순 등으로 다중 정렬됩니다. 즉, like 검색으로 그나마 시도해볼 수 있는 유사도순 정렬입니다;;