본문으로 바로가기
반응형

스핑크그 검색 엔진에서 main + delta 로 할 시 문제점이 항상 있다.

레코드가 지워지거나 했을때 해당 레코드가 지워진걸 알아 낼 수 없다는 것이다.


main + delta 구조 에서는 병합을 하고 나면 델타 인덱스의 주용 인덱스와 새로운 기록은 추가가 되지만 말이다.


그렇다면 데이타 베이스에서 오래된 레코드를 삭제 하려면 어떻게 해야 할까?


[ 문제 ]

우리가 10 개의  DOC_ID 를 가지고 있다.

우리 는 2 개의 새로운 기록이 인덱스 병합 후 11 , 12 가 추가 한다고 가정 해 보자 .

우리는 12 개의 기록 ( : 1 ~ 12 DOC_ID ) 과  인덱스가 됩니다.


그러나 우리는 또한 데이터베이스에서 레코드를 2, 4 또는 다른 레코드를  삭제 한 경우엔 어떻게 될까요?


우리가 너무 많은   ID를 반환합니다 관련 키워드 스핑크스 를 검색 할 때 인덱스 병합 따라서 스핑크스는 쓰레기 데이터를 제거 하지 않습니다.


[정답]


위 이슈 사항에 대한 정답은  ‘sql_query_killlist. 라는 것 입니다.

이것은 메인 인덱스에서 제거 하고 싶은 doc_ids 를 지정 하는 것 입니다.


이걸 어떻게 적용해 볼 수 있을까요?


일단 테이블을 하나 만듭니다.


CREATE TABLE `deleted_posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `post_id` int(11),
  PRIMARY KEY (`id`)
);
그리고 나서 디비에서 삭제가 일어 난다면 이 테이블에 insert 를 같이 해 줍니다.

sphinx.conf 파일에서 수정을 합니다.


sql_query_killlist = SELECT post_id FROM deleted_posts


저 한 줄이면 끝 입니다.


이젠 불필요한 정보는 index merging 을 하면서 main 인덱스에서 저 쿼리를 이용해서 해당 레코드는

삭제가 이루어 집니다.



전체적으로 한 번 보여 준다면 sphinx.conf 의 내용 입니다.



source main

{

  # Connection settings

  type = mysql

  sql_host = localhost

  sql_user = root

  sql_pass =

  sql_db = blog

  sql_query_pre = SET NAMES utf8


  # pre query to update the counter with max id from posts table

  sql_query_pre = REPLACE INTO posts_counter SELECT 1, MAX(id) FROM posts


  # query to fetch the records for indexing.

  # We are fetching only those records whose id is less than the max id from the counter

  sql_query = SELECT id, title, description FROM posts \

  WHERE id <= (SELECT max_id FROM posts_counter WHERE id=1) }


# Define delta source. We are extending delta from main

source source delta : main {

  sql_query_pre = SET NAMES utf8

  # fetch only those records whose id is greater than max_id i.e. those records which are not   already indexed.

  sql_query = SELECT id, title, description FROM posts \

  WHERE id > (SELECT max_id FROM posts_counter WHERE id=1)


  # parameter containing doc_ids to be removed from main index

  sql_query_killlist = SELECT post_id FROM deleted_posts


  #optional - used to empty table after record is removed from main index

  sql_query_post_index = DELETE FROM deleted_posts

}


index main

{

  source = main

  path = /path/to/mainindex

  charset_type = utf8

}


index delta : main

{

  source = delta

  path = /path/to/deltaindex

}


searchd

{

  # Port to listen on

  port = 3312


  # Next few are the paths to log files

  log = /usr/local/sphinx/var/log/searchd.log

  query_log = /usr/local/sphinx/var/log/query.log


  # Maximum amount of concurrent searches to run - 0 for unlimited

  max_children = 30


  # Path to pid file

  pid_file = /usr/local/sphinx/var/log/searchd.pid

}

이런 정보는 국내 어느 사이트에 가서도 안 가르쳐 주는 사항입니다.

물론 저도 펌글 이지만 우리 나라에서는 이 정보를 아는 사람이 없는거 같습니다.


출처 입니다.


http://www.sanisoft.com/blog/2013/06/28/remove-deleted-records-in-sphinx/




반응형