안녕하세요. 린치핀소프트 한광희입니다.

 

최근 제작했던 플러그인으로 현재 포스트별로 방문자의 수를 측정하고 기록하여 추후에 해당 데이터를 기반으로 각 “기간 별”로 조회수 기반 “랭크”를 측정하는 플러그인을 제작하였습니다.

이때, 활용했던 “pre_get_posts” 액션 훅을 설명하고 이때 제작된 데이터베이스 테이블구조를 소개해드리려고 합니다.

 

1. 이용자의 신원을 식별하지 않고, 단순히 포스트에 대한 접속조회만을 카운트 한다.

2. 주간(월요일 ~ 일요일)별로 실시간으로 조회가 랭크가 조회되어야 하며, 데이터 수집 시점 이후로 특정 기간의 주간 랭크를 확인할 수 있어야 한다.

 

대략 위의 2가지가 제작전 고려해야 할 사항으로 주요한 사항은 플러그인 기능이 지속적으로 추가될 수 있으므로 이를 고려해 포스트 조회의 “기록” 레코드를 데이터베이스에 올바르게 저장하는 방법을 생각해야 했습니다.

 

DDL SQL

CREATE TABLE IF NOT EXISTS lcp_visitors
(
  ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  POST_ID bigint(20) unsigned NOT NULL,
  visit_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY(ID)
)

워드프레스의 고유의 테이블을 활용할 생각을 해보다가, 간단한 구조로 새로운 테이블을 정의하였습니다.

초기에는 일일, 시간단위로 조회수를 합산하여 각 시간대/요일별로 하나의 레코드에서 접속된 조회수를 저장하는 방식으로 생각했습니다. 예를 들어 1시간 별로 합산 측정할 경우 포스트당 하루에 최대 24개의 레코드가 생성되도록 구성을 염두해두었다가 결국 조회하는 족족 로그처럼 테이블에 레코드가 생성되는 것으로 방향을 바꾸었습니다. 조회의 시각뿐만 아니라 분/초도 추후에 활용될수 있겠다는 생각이 들어 이렇게 방향을 정했습니다.

조회된 포스트의 ID가 “POST_ID” 테이블의 항목에, 조회된 시각이 “visit_time 테이블의 항목에 저장되도록 하였습니다. 레코드의 수는 비록 많아져도 조회시의 “SQL” 쿼리에서 “BETWEEN … AND ” 그리고 “ORDER BY ” 정렬등을 이용해서 원하는 검색범위와 정렬까지 쉽게 할 수 있음을 염두에 두고 위처럼 테이블을 제작하였습니다.

 

add_action('pre_get_posts','check_post_visit');


function check_post_visit($query){

  if(is_main_query() && isset($query->query['p']) && !is_admin())
  {

    $post = get_post($query->query['p']);
    addView($post->ID);
  }

}

“pre_get_posts” 액션 훅을 이용하여 포스트가 이용자에 의해 요청될때마다 조회수를 증가시키도록 하였습니다.  addView() 함수가 전달받은 POST ID를 기반으로 조회수를 증가 시키고 있습니다.

$query->query[‘p’] 에는 post_id 가 저장되어 있습니다. $query->query 항목으로 확인할수 있는 리스트는 https://codex.wordpress.org/WordPress_Query_Vars 에서 확인 할 수 있습니다.

 

$query =<<<HERE
SELECT POST_ID, count(*) as cnt FROM lcp_visitors
WHERE visit_time
BETWEEN '{$dates[0]}'
AND '{$dates[1]}'
AND POST_ID IN ({$post_ids_str})
GROUP BY POST_ID
ORDER BY cnt DESC, POST_ID DESC
LIMIT 0,100;
HERE;

위의 SQL 쿼리는 주어진 기간에 포스트의 조회수를 합산하여 내림차순으로 정렬하고 있습니다. 여기서는 검색되어야 하는 포스트를 우선 식별할 수 있어서 IN() 구문으로 검색의 대상이 되는 POST_ID를 먼저 지정해주었습니다.

 

 

이후에는 쿠키나 세션을 기반으로 하여 접속자의 신원을 식별하여 조회수를 측정하여 조회수가 아닌 접속자의 수로도 카운트 하는 방법으로도 발전 시켜 볼 수 있습니다.