ipアドレスの地理情報を取得してmongoDBに挿入する

192.168.33.1だとgeoliteがエラーになるので、198.7.31.23にします。

$data = array("date"=>date("Y-m-d H:i:s"));
$audience = $_POST['userdata']; 
$mongo = "app.na".$audience[0][1];
$audience = array_splice($audience, 1);

$ip_addr = $audience[0][1];
if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

foreach($audience as $value){
	$data += array($value[0]=>$value[1]); 
}

require_once '../geolite/vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('../geolite/GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$data = $data + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

var_dump($data);

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($data);
$mng->executeBulkWrite($mongo, $bulk);

echo "finished!!!";

取得できています。

mongoDBにもはいってます。

-geoliteがエラーの時の為に、try catch (Exception $e) に変えると、以下の分岐条件は削除できます。

if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

ipの地理情報はmongoDBには入りません。

因みに、Chrom extensionでBetternet Unlimited Free VPN ProxyやHotspot Shieldなどを使うとIPアドレスを偽造できるようです。

次は、表示側を作ります。
flexを入れ子にしたレイアウトにします。

mondoDBを使いたいのでcosmosDBを作成する

azure cloud shell

az cosmosdb create --name nacosmosdb --resource-group myResourceGroup --kind MongoDB

さーどうしましょう

{
  "additionalProperties": {},
  "capabilities": [],
  "consistencyPolicy": {
    "additionalProperties": {},
    "defaultConsistencyLevel": "Session",
    "maxIntervalInSeconds": 5,
    "maxStalenessPrefix": 100
  },
  "databaseAccountOfferType": "Standard",
  "documentEndpoint": "https://nacosmosdb.documents.azure.com:443/",
  "enableAutomaticFailover": false,
  "failoverPolicies": [
    {
      "additionalProperties": {},
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe"
    }
  ],
  "id": "/subscriptions/hoge/resourceGroups/myResourceGroup/providers/Microsoft.DocumentDB/databaseAccounts/nacosmosdb",
  "ipRangeFilter": "",
  "kind": "MongoDB",
  "location": "West Europe",
  "name": "nacosmosdb",
  "provisioningState": "Succeeded",
  "readLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ],
  "resourceGroup": "myResourceGroup",
  "tags": {},
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "writeLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ]
}

primary master keyを発行する

az cosmosdb list-keys --name nacosmosdb --resource-group myResourceGroup --query "primaryMasterKey"

接続

'use strict';

module.exports = {
  db: {
    uri: 'mongodb://:@.documents.azure.com:10255/mean-dev?ssl=true&sslverifycertificate=false'
  }
};

ん?

mongoDBで~以上、~以下

analytics.php

$date1 = date("Y-m-d H:i:s", strtotime("- 2 day"));
$date2 = date("Y-m-d H:i:s", strtotime("- 1 day"));
echo $date1 ."~".$date2 ."<br>";


$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$filter =  [
	'date' => [ '$gte' => $date1, '$lte' => $date2]
];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  // var_dump($document);
  $pv[] = $document->date;
  $cookie[] = $document->cookie;
  if(!is_null($document->referrer)){
  $referrer = $document->referrer;
  }
}
$uu = array_unique($cookie);
echo "<br>Users :".count($uu)."<br>";
echo "Pageviews :".count($pv)."<br>";
$bounce = (count($pv) - count($referrer))/ count($pv);
echo "Bounce rate :" .sprintf('%.2f',$bounce)."<br>";

Bounce rateは直帰率です。

Exitは離脱率なので、uniqueなsession / PVですね。やはり、sessionのIDは必要のようです。
twitterのsessionのjsonでいう、idあたりでしょうか。

PHP・mongoDBでqueryを取得する際にfilterを使う

collectionに4/15のdocumentが3件、4/16のdocumentが2件入っています。

‘$gte’ => $dateがそれ以上という意味らしいです。
analytics.php

$date = date("Y-m-d", strtotime("- 1 day"));
$date = date("Y-m-d");
echo $date ."<br>";


$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$filter = [
	'date' => [ '$gte' => $date]
];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);

$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  var_dump($document);
}

今日のデータが取得できました。

配列をchart.jsに表示したいですね。

PHP・mongoDBで比較演算子を使う

‘date’ => [ ‘$gte’ => $date]とします。

$date = date("Y-m-d");
echo $date ."<br>";


$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$filter = [
	'date' => [ '$gte' => $date]
];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);

$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  var_dump($document);
}

mongodbにトラッキング情報をinsert

挿入するのは、アクセス日時、ip、新規・2回目以降のユーザー、cookieのユニークID、リファラー、前ページの平均滞在時間、閲覧ページ

datasetは以下のような連想配列
[“date”]=> string(19) “2018-04-15 23:12:01” [“ip”]=> string(12) “192.168.33.1” [“visit”]=> string(13) “Returned User” [“cookie”]=> string(10) “a167mn677r” [“referrer”]=> string(9) “/view.php” [“avgtime”]=> string(2) “25” [“page”]=> string(9) “/view.php”

na.js
配列のkeyの名称は、google analyticsの言語をEnglish USにして参考にネーミング

var unix = Math.floor((new Date).getTime()/1E3);
var visit = "New User";
if(navigator.cookieEnabled){
    var all=document.cookie + ";";
    var cStart = all.indexOf("_na=",0);
    if(cStart == -1){   
        var char = "abcdefghijklmnopqrstuvwxyz123456789";
        var id = "";
        for(var i=0; i<10; i++){
            id += char[Math.floor(Math.random()*35)];
        }
        var expire = new Date();
        expire.setTime(expire.getTime() + 1000*3600*24*365*2);
        document.cookie="_na=NA1."+id+"."+unix+";expires=" + expire.toUTCString();
        a.push(['cookie',id]);
        a.push(['vist',visit]);
        a.push(['referrer',document.referrer]);
    } else {
        visit = "Returned User";
        a.push(['visit',visit]);
        var cEnd = all.indexOf(";",cStart);
		var cID = all.substring(cStart+8,cEnd - 11); //_na=NA1.0000000000.
		a.push(['cookie',cID]);
        var c = window.sessionStorage.getItem(['ScribeTransport']);
        if(c){
            d = JSON.parse(c);
            a.push(['referrer',d.path]);
            a.push(['avgtime',(unix - d.time)]);        
        }       
    }
}
var data = '{"path":"'+location.pathname+'", "time":"'+unix+'"}';
window.sessionStorage.setItem(['ScribeTransport'],[data]);

a.push(['page',location.pathname]);
$(function(){
    $(document).ready(function(){
            var postData = {"userdata": a};
            $.post(
                "doubleclick.php",
                 postData,
                 function(data){
                    $(".box").html(data);
                }
            );
        });
});

doubleclick.php
1.アカウントIDをmongoのcollection名にしたいので、postされたデータから、アカウントIDのみ切り抜いて、array_spliceでそれ以降をdata setにする。
2.連想配列をmongodbにinsert

$data = array("date"=>date("Y-m-d H:i:s"));
$audience = $_POST['userdata']; 
$mongo = "app.na".$audience[0][1];
$audience = array_splice($audience, 1);
foreach($audience as $value){
	$data += array($value[0]=>$value[1]); 
}
var_dump($data);

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($data);
$mng->executeBulkWrite($mongo, $bulk);

echo "finished!!!";

うおお、上手く入っている。嬉し~

同じcookie、異なるセッションでアクセスします。

あれ、待てよ、なんか違う気がしてきた。
セッションにもユニークなID発行するべきなんじゃないか...?
ちょっと混乱してきたが、queryのviewを作りながら修正していきましょう。

phpからmongodbにinsert

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['visit' => 'new user', 'referrer'=>'/']);
$mng->executeBulkWrite('app.na007', $bulk);

echo "finished";

入りました。

phpのデータが配列の場合、そのままinsertできます。

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$array = array('visit' => 'return user', 'referrer'=>'/index.php');
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($array);
$mng->executeBulkWrite('app.na007', $bulk);

echo "finished";

素晴らしい!いいですね♪

ちなみに、既にあるcollectionと同じcollectionをつくろうとすると、
以下のように、already existsとなります。
> db.createCollection(‘na007’);
{ “ok” : 0, “errmsg” : “collection already exists”, “code” : 48 }

新しく008のcollectionにdocumentを入れたい場合
->コードに変更なし

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$array = array('visit' => 'return user', 'referrer'=>'/index.php');
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($array);
$mng->executeBulkWrite('app.na008', $bulk);

echo "finished";

あ、nosqlなので、mysqlのようにifexistでtableを取得して、なければtableをcreate なんて必要はないんでした。完全に忘れていました。なんか、rubyを始めて触った時と同じような感覚になります。

phpでmongodbからデータをfind();

昨日つくったDB名:app、collection:na007をphpで取得します。

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$filter = [];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  var_dump($document);
}

Nice!
stdClassのobjectで取れるんですね。

mysqlのselectに慣れてしまったせいか、恐る恐る触ってます。
あ、twitterのsessionがjsonなのは、twitter analyticsにno sql使ってるからでしょうか?

/lib64/libc.so.6: version `GLIBC_2.14′ not found

php.iniにextension=mongo.soを通しても、
/lib64/libc.so.6: version `GLIBC_2.14′ not found

glibcのversion確認

# ldd --version
ldd (GNU libc) 2.23

2.14より新しいやんけ。。

もう嫌だ。
mongodbは諦めて、google big queryを物色し始める。
https://cloud.google.com/bigquery/?hl=ja
google big queryの料金
https://cloud.google.com/bigquery/pricing?hl=ja
>BigQuery の料金は、ストレージの定額料金とクエリの使用料金に基づいています。
>毎月 10 GB まで無料。
え、10GB? iphone8の最も低いスペックで64GBですぞ。。。

ということで、再度mongoDB phpドライバのインストールに挑戦
そもそもpearってなんだ、ということで、
pearをアップデートしてみる。

# yum update --enablerepo=remi-php56 php-pear

再度,peclをコマンドラインで打つ

pecl install mongo

Build process completed successfully
Installing ‘/usr/lib64/php/modules/mongodb.so’
install ok: channel://pecl.php.net/mongodb-1.4.2
configuration option “php_ini” is not set to php.ini location
You should add “extension=mongodb.so” to php.ini

あ~まじかよ、朝から6~7時間位、これしかやってないんですけど。

viでphp.iniに”extension=mongodb.so” を追加して、httpd restart

phpinfo()

php-pearを最新にしてpecl install mongoしないと駄目なのね。
どっか旅に出たい。