Qiitaの閲覧数をBigQueryとGoogleデータポータルで可視化する

Googleデータポータルがかっこよくグラフを作ってくれそうなので、使ってみようと思います。
作るグラフは、自分が投稿しているQiitaの記事の閲覧数です。
閲覧数の増加傾向を見れば、今何が求められているのかがわかるのではないかと思ったためです。
（いいね数の傾向だけでは、解像度が荒すぎです。）

実は、以前、以下の記事にて、AWSのDynamoDBに閲覧数を記録していました。

　[Qiitaの閲覧数をMQTTで記録する](https://qiita.com/poruruba/items/5a35503900acd6b37d70)

その後、AWSのグラフ化サービスを頑張って理解しようとしたのですが、難しくて苦労していました。
データ分析と言えば、GCPだろうということで、GCPのサービスを探していたら、BigQueryとGoogleデータポータル(Data Studio)を見つけました。

# 全体のデータの流れ

先に、データの流れの全体像を示しておきます。

クライアント側は定期的に起動しnpmモジュールを利用して、データをアップします。
アップ先は、GoogleのBigQueryです。BigQueryがデータを蓄えるデータベースの役割をします。
蓄えられたデータは、Googleデータポータルから参照されグラフを描画します。Googleデータポータルは、描画のたびにBigQueryからデータを取得するため、最新の値でグラフが描画されます。

# BigQueryにテーブルを作成する

それでは、データを保持するテーブルをBigQuery上に作成していきます。
まずは、ブラウザからGoogle Cloud Platformを開きます。

Google Cloud Platform
　https://console.cloud.google.com/home/dashboard

プロジェクトを作成していなければ、これを機に作成しておきましょう。

次に、左側のナビゲーションから、BigQueryを選択します。
以降の画面は、UIとして新しいUIを使っています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/8ea0b618-0b94-4b8f-dd2c-5ff8cd5adf97.png)
 
左側のパネルにあるプロジェクトIDを選択し、右側の「データセットを作成」を押下します。
データセットIDに適当な名前を入れます。例えば、「test_dataset」とします。
データのロケーションには「東京（asia-northeast1)を選択しておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/7a6795b9-9552-dd62-2607-33945c0cb580.png)

次に、左側のパネルから先ほど作成した「test_dataset」を選択し、右側の「テーブルを作成」を押下します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/12d1f969-330a-021f-5444-2e86e8fed165.png)

ソースは「空のテーブル」を選択します。もし、CSVファイルなどデータが手元にある場合は、「アップロード」で登録することが可能です。

プロジェクト名とデータセット名にはすでに値が入っていると思います。テーブル名には適当に「qiita」とでもしておきます。

そして、スキーマに、これから登録するデータの型を定義します。
以下のような感じにしました。

* createdat：INTEGER
* createdatstr：TIMESTAMP
* id：STRING
* title：STRING
* views：INTEGER
* likes：INTEGER

モードはとりあえず、「NULLABLE」にでもしておけばよいでしょう。
これで、以下のようにテーブルが作られ、スキーマも定義されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/6c181ba1-3883-ff48-6e6e-a526ae99be84.png)

# Credentialファイルを作成する

データの登録は、Node.jsを使ったクライアントから登録します。
その時に、テーブルにアクセスできるようにCredentialを作成しておく必要があります。

Google Cloud Platformのページにおいて、左側のナビゲーションから「IAMと管理」そして「サービスアカウント」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/bfb77670-f203-47b3-deb4-faf7574b7893.png)

「サービスアカウントを作成」のリンクをクリックします。
サービスアカウント名には、たとえば「test_bigquery」とします。
サービスアカウントの説明にはわかりやすいように例えば「BigQuery」と記入しておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/0f3a8b6e-d30c-4b80-b1d1-5a2e12eb652d.png)

役割には「BigQuery データ編集者」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/9d2840b6-5536-a56e-7f65-59babd716235.png)

最後に「＋キーを作成」をクリックしてCredentialファイルを作成します。
キータイプとしては「JSON」を選択しておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/744e672d-3097-f480-b176-5a342c74a5e1.png)

取得したJSONファイルは後で使うので大事に保管しておきましょう。


# データを登録する

データの登録には、npmモジュールを利用します。

* @google-cloud/bigquery
* dotenv
* moment
* node-fetch

一番大事なのが「@google-cloud/bigquery」です。
まさしく、BigQueryにデータを登録するためのGoogle製のモジュールです。

　https://cloud.google.com/bigquery/docs/reference/libraries?hl=ja

「node-fetch」は、Qiitaから記事の閲覧数を取得するために使います。詳細は、以下を参照してください。

　[Qiitaの閲覧数をMQTTで記録する](https://qiita.com/poruruba/items/5a35503900acd6b37d70)
　https://qiita.com/api/v2/docs

「dotenv」は、Credentialファイルのファイル名を指定するのに使います。
「moment」は、ご存じ日付表示するためのモジュールです。

それでは早速、ソースコードを見てみましょう。

```:index.js
const fetch = require('node-fetch');
require('dotenv').config();
const { URLSearchParams } = require('url');
var moment = require("moment");

const QIITA_PRIVATE_TOKEN = process.env.QIITA_PRIVATE_TOKEN || 【Qiitaの個人用アクセストークン】;
var base_url = 'https://qiita.com/api/v2';

const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();
const dataset = bigquery.dataset('test_dataset');
const table = dataset.table('qiita');

async function bigquery_insert( data ){
    return new Promise((resolve, reject) =>{
        table.insert(data, (err, apiResponse) =>{
            if (err) {
                console.log(JSON.stringify(err));
                return reject(err);
            }
          
            console.log('insert ok');  
            console.log(apiResponse);

            resolve(apiResponse);
        });
    });
}

async function aggregate_views(){
    try{
	var messages = [];
       var json = await do_get_token(base_url + '/authenticated_user/items', { page: 1, per_page: 100 }, QIITA_PRIVATE_TOKEN )
//        console.log(json);
        for( var i = 0; i < json.length ; i++ ){
            console.log(json[i].id);

            var id = json[i].id;
            var item = await do_get_token(base_url + '/items/' + id, {}, QIITA_PRIVATE_TOKEN )
    //        console.log(item);

			var date = moment();
			var createdat = date.unix();
			var createdatstr = date.format("YYYY-MM-DD HH:mm:ss");
            
            var message = {
                id: id,
                title: item.title,
                views: item.page_views_count,
                likes: item.likes_count,
                createdat: createdat,
                createdatstr: createdatstr
            };
            
			console.log(message);
            messages.push(message);
        }

        await bigquery_insert(messages);
    }catch(err){
        console.log(err);
        process.exit();
    }
}

function do_get_token(url, qs, token){
    var params = new URLSearchParams();
    for( var key in qs )
        params.set(key, qs[key] );

	var p = params.toString();
	var url_params = url + ((!p) ? '' : ('?' + p));
    console.log(url_params);
    return fetch(url_params, {
        method : 'GET',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization' : 'Bearer ' + token }
    })
    .then((response) => {
        return response.json();
    });
}

aggregate_views();
```

【Qiitaの個人用アクセストークン】は、各自の環境に合わせて設定してください。

先ほど取得したCredentialファイルは、このindex.jsと同じディレクトリにおいてください。
そして、.envにそのファイル名を指定します。

```:.env
GOOGLE_APPLICATION_CREDENTIALS="./【Credentialファイル名】"
```

あとは、以下のように実行すれば、BigQueryに登録されるはずです。

> node.js index.js

データは、BigQueryのStreaming bufferに積まれるそうです。その値が実際に登録されるまでには少し時間がかかるようです。

# 登録されたデータを確認する

登録されると、BigQueryでテーブルを選択し、プレビュータブを選択すると、登録されたデータが表示されます。ただし、一部のデータのみなので、あくまで参考程度に思ってください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/f565c067-5c47-639a-8c72-2c0fa82b8ba7.png)

# Googleデータポータルでグラフにする

それでは、Googleデータポータルを開きましょう。

Googleデータポータル
　https://datastudio.google.com/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/b5ecd78f-3d22-6cbc-c6c8-c5eac3a71594.png)

左側のナビゲータから「データソース」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/7d4fb7f0-02bb-f214-2846-988789550d9d.png)

そして、右下の「＋」ボタンを押下します。
たくさんあるGoogleコネクタから、「BigQuery」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/6dd630c9-a824-5e16-ac87-16fe5456dc6b.png)

そうすると、BigQueryで作成したデータセットと表が見つかるかと思います。
「接続」ボタンを押下します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/f1426eae-8a89-3d51-7ffd-0e8ce03de204.png)

スキーマが表示されます。
この中で、使わないデータは無効化するとよいでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/88152042-acdc-b617-f2b3-3f04be99ed8b.png)

ここで、createdstrのタイプとして、日付（YYYYMMDD）であることを確認しておきましょう。（日付 時（YYYYMMDDHH）というのも選択できますが、今回は前者にします。）

次の画面が表示されますが、「レポートに追加」ボタンを押下して先に進めます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/4a7b1fa4-c462-13b1-a486-3ade37c0ff23.png)

さあ、これからいよいよグラフを作ります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/a49034cd-07a6-ff37-fb49-dec915a4056d.png)

上にある「グラフを追加」から「期間」の「時系列グラフ」を選択しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/ef7169e6-0daa-d3c7-26ae-74cf9ad36bd5.png)

なんか変なグラフが出てきましたが、これから設定を変えていきます。

内訳ディメンションを「title」に変更します。
指標を「views」に変更し、SUMとなっているのを「最大値」に変更します。
そして、念のためですが、スタイルを選択して、全般の欠落データとして「線を途切れさせる」を選択しておきます。
ついでに、見やすくするためにグラフの幅を広げておきましょう。
それっぽく見えてきました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/d5f069f1-dfe7-3f3f-a769-c6916656b3b6.png)

次に、上側にあるフィルタオプションを選択して追加します。
ディメンジョンは「title」にします。
また、スタイルのエキスパンドのチェックボックスはOffにしておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/f0a87d84-cfe5-e037-5621-b94d3f690ca0.png)

次に、上側にある期間を選択して追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/39816337-36b6-c0d6-1f3d-fd6c027543d2.png)

次に、追加した期間とグラフをコントロールキーを押しながらそれぞれクリックして両方を選択状態にしたうえで、右クリックしてグループをクリックします。

その時、右側のグループのプロパティにおいて、データソースに「qiita」、期間のディメンションに「createdatstr」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/f121272c-386c-11de-8861-4d6f3c50c1ab.png)

ちょっとだけ見栄えをよくするために、右上にテキストを追加してみました。
最後に、右上にこのレポートの名前を付けてあげました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/9f7eec96-f4b9-2389-7cea-d45f6b7efd27.png)

一応、これで完成、かな。
右上の「ビュー」ボタンを押下して、参照モードにしましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/7310b587-9200-db33-6128-8236a5a791e6.png)

上記の絵は、左上のタイトルのところで、以下の記事のみを選択したときのものです。

・SwaggerでLambdaのデバッグ環境を作る(1)
・SwaggerでLambdaのデバッグ環境を作る(2)：Helperライブラリを使ったLambdaの書き方
・SwaggerでLambdaのデバッグ環境を作る(3)：Dialogflowをデバッグする
・SwaggerでLambdaのデバッグ環境を作る(4)：Alexaをデバッグする
・SwaggerでLambdaのデバッグ環境を作る(5)：Clovaをデバッグする
・SwaggerでLambdaのデバッグ環境を作る(6)：GCPのCloud Endpointsをデバッグする

無事にグラフが表示されました。さらに、期間を選択すれば、選択された期間のみグラフに表示することができます。

ちなみにですが、今回グラフ化することで、閲覧数の傾向を見ることができました。

「(5)Clovaをデバッグする」が、5番目に投稿したにも関わらず、3番目の「(3)Dialogflowをデバッグする」を閲覧数で追い抜きました。意外にDialogflowは人気がないのでしょうかね。。。
「(4)Alexaをデバッグする」も同様で伸び率は大きく2番目の閲覧数に躍進しています。

こんな感じで、いいね数だけでは今まで見えなかった傾向が見えてくるかもしれません。

他にも、覚えきれないたくさんの機能があるそうです。今後いろいろ試してみようと思います。

データポータルのヘルプ
　https://support.google.com/datastudio#topic=6267740


# Webページに張り付ける

最後に、作ったグラフをWebページに張り付けたいと思います。
それには、共有という機能を使います。

上の方にある「このレポートを共有」ボタンを押下します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/51eeadb3-5f4f-73a4-ef57-a6e0998936b8.png)
 
共有可能なリンクを取得 をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/9b694670-2c51-bb42-6819-dfcc8878937e.png)
 
すると、URLが取得されます。
次に、編集ボタンを押下して編集モードにし、
「<>」という形の「このレポートを埋め込みます」 をクリックします。
そこで、埋め込みを有効にするのチェックボックスをOnにします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/09c6c026-18cc-1427-3ec5-daeef8983374.png)

そうすると、iframeを使った埋め込み方式と、単なるURL形式のコードが表示されますので、好みのコードをWebページに張り付けてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/d5a9041b-70ef-fbcf-d36f-950589ecf1c1.png)

以下が、埋め込み方式の場合です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/64a9fcc8-77b1-c1ef-a540-eaecfb0d5325.png)
 
以下がURLを直接ブラウザで参照した場合です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/ee80f3ad-2c08-7b3a-a692-7a634b0e29e3.png)

一応お伝えしておくと、上記のページはいずれも、タイトルの絞り込みや期間の選択が可能で、選択するとグラフの表示も切り替わるので、かっこいいです。


# (参考) CSVファイルからBigQueryに登録する

BitQueryにCSVファイルからデータを登録する方法について説明しておきます。
テーブル作成時に、CSVファイルを選択して登録することが可能です。
この時、スキーマを自動検出にしておくと楽です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/dcf3d32e-b598-2a63-7e91-8153419353de.png)

こんな感じで登録されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/08652717-579d-4f8b-eb46-2c7d3162c656.png)

この時、スキーマのフィールド名がわかりにくい名前が付けられた状態となります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/de50385c-841b-cda9-be90-6440c790932c.png)


このままだとわかりにくいので、以下のSQLのクエリを実行して、必要な項目だけを選択し、なおかつ、項目名をわかりやすい名前に変換することができます。

```
#standardSQL
SELECT
int64_field_1 AS createdat, timestamp_field_3 AS createdatstr, string_field_4 AS id, string_field_5 AS title, int64_field_6 AS views, int64_field_7 AS likes
FROM
XXXXXXXX.test_csv
```

このとき、「展開」から「クエリの設定」を選択し、以下のように設定しておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/d70e995e-40ed-4608-bf30-092398969e6f.png)

送信先の「クエリ結果の抽出先テーブルを設定する」のチェックボックスをOnにし、変換結果を格納するテーブル名を入力します。同じテーブルに上書きする場合には、抽出先テーブルの書き込み設定で「テーブルを上書きする」を選んでおきます。

最後に、「実行」ボタンを押下することで、データが変換されたテーブルができあがります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/1be34a47-8353-ca16-0b42-fb0a7a0a64f8.png)

以上