見出し画像

Datomic Analytics

(これは「week-of-datomic」四日目の記事です)

前回はアプリケーションロジックをデプロイするところまで作りましたが、このままだどアプリケーション側に蓄積されたデータがサイロ化するので今回は分析基盤と繋げてみようと思います。

アーキテクチャー

Datomic は内部のデータを SQL(Apache Presto)のインタフェースを通じて外部に公開することが可能です。

画像1

Access Gateway が Presto Coordinator の役割を兼務しており、Query Group を Worker として指定できます、そこで分析用の Query Group を作っておくとプロダクション環境とリソースの競合が発生しないので最新のデータを参照できる分析環境を得られます。

テーブル化とメタデーター

Datomic のデータ構造(以下 schema)は柔軟でキーバリューからテーブル、それとグラフすら自由に表現できますが、SQL のインターフェースで公開する場合は一旦テーブル構造にダウングレードしないといけません。そこで Datomic の schema を SQL の schema に動的マッピングするためのメタデーター(Datomic 用語では Metaschema)が必要です。

まずは公式のガイドに従って catalog の設定を行い、Access Gateway を再起動すると Presto server が起動します。

そこで Metaschema を設定して同じくアップロードするのですが、今回は「MusicBrainz」データセット(音楽業界のアーティストと曲のデータベース)を使っているためこのような設定を行います。

;; mbrainz.edn
{:tables ;; :membership-attr->opts
 {:abstractRelease/gid {}
  :artist/gid {}
  :country/name {}
  :artist.type/name {}
  :artist.gender/name {}
  :label.type/name {}
  :label/gid {}
  :language/name {}
  :medium.format/name {}
  :release.packaging/name {}
  :medium/format {}
  :release/gid {}
  :script/name {}
  :track/name {}}

 :joins ;;ref-attr -> tablename
 {:abstractRelease/artists artist
  :label/country country
  :label/type label_type
  :release/country country
  :release/language language
  :release/script script
  :release/packaging release_packaging
  :release/artists artist
  :release/labels label
  :artist/country country
  :artist/gender artist_gender
  :artist/type artist_type
  :medium/format medium_format
  :medium/tracks track
  :track/artists artist}}

上半分の「:tables」キーはデータの構造を示しております。Datomic のデータは一つの Entity ID に対して不特定多数のアトリビュートが紐付いてますが、SQL で表現する場合どのアトリビュートをベースにテーブルとして表示するのか決める必要があります。主キー(Primary Key)などがある場合はそれをる要するのですが、ない場合でも問題ありません。

「:artist/gid {}」は「:artist/gid」というアトリビュートが紐付いている entities を全て一つのテーブルにまとめるという表現になります、その際にデフォルトで同じ名前空間(:artist)のアトリビュートを全てテーブルの項目として表現しますが、細かい微調整が必要であれば別途設定できます。

「:tables」が定義された状態でテーブルが Presto 経由でアクセス可能になるのですが、複数のテーブルを結合する場合は SQL 側で JOIN 文を書くより Datomic 側で予め結合されたデータマートを用意した方が効率的です。そこでファイルの下半分「:joins」キーで結合可能な項目と参照先を設定しておくと Datomic 側でデータマートを用意してくれます。

動作確認

まずは VPN にアクセスできるようにプロキシを起動して

datomic-access analytics <システム名>

まずは Apache Presto CLI を使って接続してみましょう。

presto --server localhost:8989 --catalog <Datomicシステム名> --schema <Datomicデータベース名>

成功すれば SQL の REPL が表示されますのでコマンドを使って確認します。

presto:mbrainz_test> show schemas;
       Schema         
-----------------------
information_schema    
mbrainz_test          
(3 rows)

見慣れている SQL なのでテーブルの一覧も出せちゃいます

presto:mbrainz_test> show tables;
          Table           
---------------------------
abstractrelease           
abstractrelease_x_artists 
artist                    
artist_gender             
artist_type               
country                   
db__attrs                 
db__idents                
label                     
label_type                
language                  
medium                    
medium_format             
medium_x_tracks           
release                   
release_packaging         
release_x_artists         
release_x_labels          
release_x_media           
script                    
track                     
track_x_artists           
(22 rows)

もし「:db.cardinality/many」の項目があった場合は自動に中間テーブルを作ってくれます。例えばアルバム(release)に対して複数のアーティスト(artist)が紐付くことができるので「release_x_artists」テーブルとして表現されます。

presto:mbrainz_test> describe artist;
   Column     |  Type   | Extra | Comment 
---------------+---------+-------+---------
sortname      | varchar |       |         
name          | varchar |       |         
type          | bigint  |       |         
type__name    | varchar |       |         
country       | bigint  |       |         
country__code | varchar |       |         
country__name | varchar |       |         
gid           | varchar |       |         
startday      | bigint  |       |         
endday        | bigint  |       |         
startyear     | bigint  |       |         
endmonth      | bigint  |       |         
endyear       | bigint  |       |         
startmonth    | bigint  |       |         
gender        | bigint  |       |         
gender__name  | varchar |       |         
db__id        | bigint  |       |         
(17 rows)

もちろん検索もできますし、JDBC が使える環境だったらどこからでもつなげることができます。

presto:mbrainz_test> select * from artist limit 10;
                           sortname                            |                 
----------------------------------------------------------------+-----------------
Mad Curry                                                      | Mad Curry       
Renaissance                                                    | Renaissance     
Atlantis                                                       | Atlantis        
NULL                                                           | NULL            
Plus                                                           | Plus            
Juan y Junior                                                  | Juan y Junior   
Numminen, M.A. ja Jani Uhleniuksen uusrahvaanomainen orkesteri | M.A. Numminen ja
Chicory Tip                                                    | Chicory Tip     
Sui Generis                                                    | Sui Generis     
Musselwhite, Charlie                                           | Charlie Musselwh
(10 rows)

例えば先日 BI ツールの Looker から JDBC 経由で Datomic に繋げた記事も公開してあるのでよかったら参考にしてみてください。

Analytics の注意点としては
・リードオンリー、SQL からはデータを変更することができません
・特に ETL を回しているわけではなく、全てが動的にマッピングされています
・Query Group を分けていればプロダクションに影響を与えない
・現時点(2019-12-06)ではまだ Preview のため、将来的に仕様が変わることがあります

サンプルコード

今回作成したコードを公開しております。

よかったらコードを確認しながら読んでみてください。

この記事が気に入ったらサポートをしてみませんか?