Web+DBにも特集が組まれたElectronが気になっています。
WEBの技術でGUIクライアントアプリが作れるのですが、どうにもNode.jsというのが..
個人的にはQt5とかWPF/C#とかで書きたいのですが、それだとWindowsだけになっちゃうのが辛い。
似たようなものでNW.jsを見つけました。
が、これだったらElectronの方がよさそう。
でもNode.JSかぁ..(´・ω・`)
色々な事を考えていたら、ハマったのでその記録。
Postgresのバージョンは9.5.3です。(正確にはPipelineDBの0.9.5です)
例えば、以下のテーブルがあります。
CREATE TABLE imp (campaign_id BIGINT, campaign_creative_id BIGINT, imp_count BIGINT, CONSTRAINT pk_imp1 PRIMARY KEY (campaign_id, campaign_creative_id)); |
これを次のようにまとめたいとします。なんとなくやりたい事は理解してもらえると思います。
SELECT |
期待する結果としては次のようになります。
INSERT INTO imp VALUES(100, 1000, 111); |
campaign_id | campaign_creative_id | imp_count | vimp_count | click_count | conv_count |
ただし欲しい情報は全部ではないので、campaign_idで絞り込みます。
最終的にはFUNCTIONにして可変長引数としてbigint[]
を受け取り、それをcampaign_id = ANY(campaign_ids)
みたいな事をしますが、問題を簡単にするためにひとまず1件のcampaign_idを指定します。
ダミーデータで実行してもあまり意味が無いので、手元にあるテーブルを使います。
テーブル名が上記のサンプルからがらりと変わりますが、適宜脳内変換をして頂ければ…
SELECT |
※imp.campaign_id
ではなくcampaign_id
WHERE句に書いたフィルタリングは結合の後に実行されます。
campaign_id | campaign_creative_id | imp_count | vimp_count | click_count | conv_count |
Hash Full Join (cost=257.71..361.29 rows=8 width=96) (actual time=0.051..0.056 rows=1 loops=1) |
SELECT |
※今回のケースではAND
で繋げるのはNG。とてもひどいことになった気がする。
Merge Full Join (cost=418.50..510.92 rows=31 width=96) (actual time=0.034..0.035 rows=1 loops=1) |
https://www.postgresql.jp/document/9.5/html/queries-table-expressions.html
この理由はON句の中の制約は結合の前に処理され、一方WHERE句の中の制約は結合の後に処理されることによります。 これは内部結合には影響がありませんが、外部結合には大きな影響があります。
JOINは結合前にフィルタリングされる。
SELECT |
あれ..この時点で結果が違うぞ..
campaign_id | campaign_creative_id | imp_count | vimp_count | click_count | conv_count |
こうでした。
SELECT |
campaign_id | campaign_creative_id | imp_count | vimp_count | click_count | conv_count |
これを元にフィルタリング。
SELECT |
期待する結果にならないな.. FULL OUTER JOINは難しい。
そもそも何をしたいかと言うと、WHERE句に書くとJOINした後のフィルタリングなので、JOINする前に必要な情報だけに削ってからJOINしたい。
という事は、campaign_id=102で絞った各テーブルを結合する事になる。
WITH構文
WITH |
Hash Full Join (cost=58.33..58.70 rows=8 width=96) (actual time=0.071..0.075 rows=1 loops=1) |
あれ..随分遅くなった..
件数が少ないからかしら。
各テーブルに10万件
WITH RECURSIVE tmp(c1,c2,c3) AS ( |
なんだかんだでWITH構文(CTE)使う方法が一番良いっぽい。
最終的には、WITHで絞り込んだ情報をJOINすると、240msくらいから0.1msくらいまで高速にできました。
とはいえ、やりたいことはこれではなく、この続きでまた躓くことになるのです。
(PostgresではなくPipelineDBの不具合によって..)
サンプルは普通に動きますが、サンプルを動かしただけでは実際にハマりどころが分からないので、実際のデータを使ってみるよ。
調べながら書いた自分用のメモなので、非常に見にくいと思います。
https://aws.amazon.com/jp/blogs/aws/amazon-kinesis-analytics-process-streaming-data-in-real-time-with-sql/
Kinesis Analyticsというものが発表されまして、Kinesisに対してContinuous Queryを実行できるものです。
端的に言えばNorikraみたいなものです。
PipelineDBにも似ている気はしますが、PipelineDBの最大の特徴である結果を保持しておいてSQLで取り出すという事は出来ないので、個人的には競合にはならなそうですね。
お手軽感で言えばConsumerを既に持っているのであれば、PipelineDBの方に軍配が上がります。(PipelineDBはkinesis connectorも実はあります)
まだ日本リージョンでは使えないので、OregonにKinesis Streamを作り、一部のproductionのデータをそちらにもコピーするようにしました。
気になった事を列挙していきます。
error_stream
という物が存在するh
やw
などの1文字はNG[a-zA-Z][a-zA-Z0-9_]+
このパターンじゃないと駄目timestmap
, rank
とか駄目Amazon Kinesis Analytics supports only Java single-byte CHARACTER SETs.
とDocumentに書いてあるPARTITION_KEY VARCHAR(512)
SEQUENCE_NUMBER VARCHAR(128)
SHARD_ID VARCHAR(64)
APPROXIMATE_ARRIVAL_TIME TIMESTAMP
Save schema and update samples
のボタンを押してもNo rows in source stream
と言われる事がある。No rows in source stream
って言われる。Amazon Kinesis Analytics console does not support managing reference data sources for your applications. You can use the AWS CLI to add reference data source to your application.
ここまでで、自分のデータでクエリをかけるところまではできた。
が、IAM Roleに権限を追加しても、未だにS3のファイル参照は出来ていない。
ひとまず調査はここまでにして、気になった事をサポートに投げています。
awscliを最新の状態にする(試した時は 1.10.56)
s3://bucket*/tamtam-test/kinesis_analytics/devices.csv
deviceType,name |
# version-idを見る |
devices-input.jsonの中身です。一部マスクしてます。
エラーが出て良くわからない場合は、--debug
を付けて実行すると良いです。
{ |
Real-time Analyticsのタブには出てくるんだけど、中身を見ようとするとエラーになる。
参考) http://docs.aws.amazon.com/kinesisanalytics/latest/dev/app-add-reference-data.html
|
これで参照できない。
どうやら参照する時に内部的に大文字に変換していて、スキーマ定義の列が大文字ではないので、そんな列はないぞと言われる。
いくつかのパターンを試してみましたが、スキーマ定義は大文字必須のようだ。
追記: 2016/08/14
サポートの人から教えて貰いまして、ダブルクォートで括らないと大文字に変換されるそうです。ダブルクォートで括れば、スキーマ定義が小文字のままでも参照できます。
http://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sql-reference-identifiers.html
追記: 2016/09/04
何も操作できなかった問題は、GUIで色々と弄っていたらIAM Role(のポリシー)のPermissionがおかしくなってました。
しかも1つのApplicationに複数のポリシーが紐付いていて、その状態だと画面を開く度にポリシーのバージョンが更新されていってしまう。。
これはもうGUIの不具合という事で片付けて、深追いしないことにしました。
CURRENT_ROW_TIMESTAMP
W3C_LOG_PARSE
RANDOM_CUT_FOREST
http://jmlr.org/proceedings/papers/v48/guha16.pdf
iOSアプリのテストをしていて、起動時にIDFAが毎回変わっている気がする。
これではターゲティングが出来ない😨 という事で、調べてみたところ、以下のページを見つけました。
http://dev.tapjoy.com/faq/testflight-idfa-and-testing-tapjoy/
http://stackoverflow.com/questions/26648840/ios-testflight-beta-app-get-new-advertising-identifier-in-each-run
Namely, each time a Testflight-distributed app asks for the the Identifier for Advertisers (IDFA), it will get a different IDFA.
TestFlightの場合、IDFAを取得する度に異なるIDが返ってくると.. まじかよっ😨
アプリでは起動時にIDFAを取得してキャッシュしていたので、起動する度に変わっていたように見えていただけなのね。
こちらの勉強会です。
http://connpass.com/event/35264/
参加者がガチ勢ばっかりだったので、マジびびる..
途中で海外のMeetup方式になってマジびびる…
スライドはここに置いておきます。
http://www.slideshare.net/tamrin69/pipelinedb
streamのpostgres上の実装とか、continuous viewはviewなので実体が別に_mrelテーブル(とシーケンステーブル)が存在するとか言いたかったのですが、時間が無くなってしまい殆ど駆け足でした。
知りたい事があれば個別に聞いてください。
また、弊社のランチを食べながら話をしたいという方もTwitterでコンタクトくださいませ。
一部の人にはStream Processingよりも重複排除の方が引っかかったようで、発表後や懇親会ではそういうお話が出来て楽しかったです。
個人的には、予測モデルの生成のような難しい事をするのであればそれに適したミドルウェアを使えば良いと思いますが、単純にKPIを素早く出したいだけだったらPipelineDBが優れているなと思いました。
(そもそも同じ土俵で戦う製品では無いし)
主催者の方、および会場提供のY!さんありがとうございました。
ほんとガチな人しか居なかったし、発表もガチな内容しか無かったので楽しかったです。
LavernaはElectronベースのOSSです。
web-sequence図やdot形式の図が描画できたら良いなぁと思って、ちょっと開発環境を整えてみます。
READMEにある通りですが、
npm install -g bower |
みたいな感じです。
起動する時は、以下のように起動します。
electron . |
この場合はブラウザが立ち上がりますが、アプリとして起動する場合は、以下のように--noServer
を付けます。
electron . --noServer |
一番最初に --noServer
を付けて起動するとアプリの中身が何も表示されなかったので、最初は普通に起動する必要があるっぽいです。
開発モード(Inspectorとか表示される)をONにして起動する場合は、--dev
をつけます。
electron . --noServer --dev |
Macの場合、~/Library/Application Support/laverna/
にキャッシュが保存されているので、これを消します。
Localeを編集した時、一向に反映される気配が無くて、インストールし直してもビルドし直しても駄目で、これが原因でした。
Evernote、最近雲行きが怪しい。Premium契約をしているけど、一向にテンプレートの機能が追加されないし、別のに乗り換えようかなと思っています。
その前はOneNote使っていたのですが、これはこれでちょっとアレなんですよね。
今は、Quiverというアプリを使っていて、Mac専用。。
Quiverの良いところは、1つのページにブロックの概念があって、MarkdownやCode等を貼り付けられること。Sequence図も書ける。ただMac専用..
欲しい機能としては、
そこで見つけたのがlavernaというアプリ。
Linux, Windows, Macで動く上にブラウザでも使える。しかもOSS。
スマフォ版アプリは無いけどAndroid版が出来るらしい。
Web版はDropboxと連携する事でドキュメントを保存する事ができます。
ただ、Webで貼り付けた画像がMacでは読み込めません。逆もまたしかり。
画像はDropboxに保存されるわけではないっぽい。残念..
他にはsimplenoteというものがあるらしい。
日本語で説明が難しい。のでやりたい事をコードで。
exec_service.submit(new Callable<String>(){ |
これをLambdaで書くと、
exec_service.submit(()->{ |
こうなるわけだけど、ここに@Trace
を設定するにはどーすれば良いか。
結論としては無理っぽい。(´・ω・`)しょぼーん
http://stackoverflow.com/questions/23968736/annotated-lambda-expression-instead-of-interface-with-single-apply-method/23983479#23983479
http://stackoverflow.com/questions/22375891/annotating-the-functional-interface-of-a-lambda-expression
SlackにUploadされたファイルをGoogleDriveに自動で保存していくコードをRubyで書いていたのですが以下の現象が発生していました。
ちなみにZapier等を使わなかったのは、何かの必要な情報が取れなかったからです。(昔の事なので忘れた..)
現象: Googleドライブにアップロードしたファイルをブラウザからダウンロードした時、ファイル名に謎の拡張子がついてしまう。
例えば、sample.png
という名前でアップロードしているのにsample.png.file
という名前でダウンロードされます。
原因は以下のようなコードでした。child_title=sample.png
, local_file=tmp.file
, mime=image/png
としていました。
中身のコードを追っていないので適当な推測ですが、title
はファイル名にはなってくれますが、ダウンロードした時の拡張子はそのようになるわけではないっぽいです。
request_schemaの設定かmediaの設定あたり、何か足りていないのかしら..?(´・ω・`)
https://developers.google.com/drive/v2/reference/files/insert#request-body
によると、originalFilename
かしら?
require 'google/api_client' |
この前ハマったので、備忘録メモ。
http://stackoverflow.com/questions/6435267/java-enum-static-final-instance-variables
EnumをEnum名(.name())とは別の特定のキーから逆引きできるコードを書きたくて、以下のように書いてみました。
import java.util.HashMap; |
すると、こんなエラーが出ました。
Cannot refer to the static enum field MyEnum.lookupMap within an initializer
コンストラクタ内でstatic変数を参照しているのがNGのようです。
通常のクラスの場合、staticイニシャライザが最初に実行されるのですが、
Enumの場合は、staticイニシャライザよりもinstanceのコンストラクタの方が先に実行されるようです。
というわけで、こう書きます。
import java.util.HashMap; |
もしくは、InnerClassでHolderクラスを作ります。こっちの方がスマートですね。
この場合、Holder#static{}
が一番最初に呼び出されるので、MyEnumコンストラクタから直接参照できるわけです。
import java.util.HashMap; |
Enumと普通のクラスの初期化順を確認するコードです。
public class InitOrderTest { |
classの場合は、static -> {} -> ()
という順番に対して、Enumの場合は、{} -> () -> static
という順番になっています。
main |