先のエントリーでData APIのGA PVをとるところではまっていると書きました。今回はそれの原因が特定できたのでまとめてみます。
まずは自分が前回書いた内容は全部ハズレだったという事。いやぁ勘がにぶったなぁ。
戻り値のJSONをもうちょっと良く見てみたら、なんと同じURLを持ったitemが2つあるものが。一つはtitleが正しくセットされているもの。もう一つはtitleが(not set)となっているもの。
もうちょっと調べてみるとGA APIを叩いた時に既にtitleが正しいものと(not set)の物があるみたい。これはGAのjava scriptがページ閲覧時に読み込まれた時に通常は正しくtitleがセットされるのに、何かしらの理由でセットされない状況があるのかな。そうすると、同じURL(path)に対して2つのitemが戻ってきてしまう。
MT::DataAPI::Endpoint::Statsの中ではURL(path)はユニークなものとして設計されており、ハッシュのキーとしても用いられています。データのitemのポインタをURL(path)を使って指定しているため、上位から順番に$data->{items}のオブジェクトを指定していくと、titleが正しくセットされたitemではなく、(not set)となっているitemがそのURL(path)のオブジェクトとして$items{$path}に指定されてしまいます。
そうすると、archiveTypeやentry_idなどはtitleが正しくセットされている上位のitemオブジェクトではなく、正しくない(not set)となっている下位のオブジェクトに代入されます。これにより、上位にarchiveTypeがundefになっているオブジェクトが散見されるようになるという事です。
limitを200から30にして一見状況が改善されたように見受けられたのは、30位以内にtitleが(not set)となっているitemがなかったため。limitを増やせばそれがだんだん増える訳で、またPVが多ければそれだけ(not set)となる確立が高くなるため上位にundefになる物が増えていくという状況の説明にもピッタリと当てはまります。
(そしたらPerlデバッガで直接叩いても状況は変わらないはずだけど、、、見間違い??、、、)
根本的な解決としては、titleが(not set)となっているitemは、正しくセットされている物にその分のPVを加算し、$data->{items}から削除するのが良いのかなと思うのですが、ちょっとヘビー。そこで次点としてtitleが(not set)となっている物は無視するという風にコードをいじってみました。(80行目前後)
-$items{$path} = $i;
+$items{$path} = $i unless $i->{title} eq '(not set)';
これでOK。limitを200件にしても上位itemのarchiveTypeがundefになる事はなくなりました。
この方法だと(not set)となっているPV数が多くなるとランキングに若干の差が出てしまうのですが、そこまで厳密なランキングではないので、このような変更でとりあえず良しとしました。
方法は問いませんが、コアでも修正される事を願っています(^^)
追記)コアでも修正されました。私が修正したのよりも美しく修正されていますw。
https://github.com/movabletype/movabletype/commit/3dd6d275e98894afa973e3311fda2b14fc179a8a
Movable Type 6 本格活用ガイドブック (Web Designing BOOKS) | |
藤本 壱 柳谷 真志 奥脇 知宏 シックス・アパート株式会社 マイナビ 2013-11-30 売り上げランキング : 80852 Amazonで詳しく見る by G-Tools |