serverless での エラーマッピングの仕方。
そもそものエラーの返し方はこちら。
return context.done(new Error("invalid type :" + type ));
レスポンスコードを変えたりしたい時は、 s-function.json の responses をいじる 。
こんな感じでコンソール上の「Lambda Error Regex」を「selectionPattern」に 設定する。
デフォルトだとstackTraceがそのまま出てしまうのでテンプレートを設定している。
"responses": { "400": { "statusCode": "400", "selectionPattern": "invalid type.*", "responseTemplates": { "application/json": "#set($inputRoot = $input.path('$'))\n{\n \"errorMessage\": \"$inputRoot.errorMessage\",\n \"errorType\": \"$inputRoot.errorType\"#if($context.stage == \"development\"),\n \"stackTrace\": $inputRoot.stackTrace#end\n\n}" } },
テンプレートを見やすく整形するとこんな感じ。
stageでstackTraceの出力を切り替えている。
#set($inputRoot = $input.path('$')) { "errorMessage": "$inputRoot.errorMessage", "errorType": "$inputRoot.errorType"#if($context.stage == "development"), "stackTrace": $inputRoot.stackTrace #end }
serverlessのs-function.jsonに設定する値
この辺を見ながらやる感じ? docs.aws.amazon.com
serverlessのmappingtemplateのフォーマットメモ
responseTemplatesのforeachとかは、ここの記述フォーマットに従っている。
Apache Velocity - VTL Reference
jsonのフィールドの先頭に「_」があった時にうまくテンプレートに適用できなかった。
そんな時はここを見るといい感じ。
serverless はまった
serverlessはnode v4以上必須なのだが
lambdaのnodeはv0.10なので
classとか使うと怒られます。
ローカルのテストの意味が。。。ねぇ!!
serverlessで一つのfunctionをrunする方法
公式ドキュメントには
sls function run myModule/myFunctions#functionOne
って書いてあるけど実際にそれでやっても
Serverless: Select a function to run: myFunctions > functionOne functionTwo
ってなっちゃうのでもやもやしてた。
こう書いたら選択しなくてもテストできるのですな。
sls function run -n functionOne
serverless さわってみた
所感
serverless (旧名JAWS)の使い勝手を調べてみた。
結果としては割といい感じ。
serverlessならansibleとかもいらなくなる!
AWSのリソースもserverlessの中のCloudFormationでOKだぜ!!みたいな。。?
まだまだドキュメントは少ないけど、もうちょっと勉強していこうと思う。。
手順
初期セットアップ
※Node 4系以上が必要
$ sudo npm install serverless -g
$ mkdir ~/.aws
$ vi ~/.aws/credentials
--
[default]
aws_access_key_id=<<アクセスキー>>
aws_secret_access_key=<<シークレットアクセスキー>>
--
$ vi ~/.aws/config
--
[default]
region = ap-northeast-1
--
作ってみる
$ serverless project create
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v.0.0.12
`-------'
Serverless: Enter a project name: (serverlessN1A2rULrx) akira-test
Serverless: Enter a project domain (used for serverless regional bucket names): (myapp.com) akira-test.com
Serverless: Enter an email to use for AWS alarms: (me@myapp.com)
Serverless: Select a region for your project:
us-east-1
us-west-2
eu-west-1
> ap-northeast-1
Serverless: Select an AWS profile for your project:
> default
Serverless: Creating a project region bucket on S3: serverless.apnortheast1.akira-test.com...
Serverless: Creating CloudFormation Stack for your new project (~5 mins)...
Serverless: Successfully created project: akira-test
- 作られたもの
- S3
- IAM Group
- IAM Role
- ディレクトリ構成
-rw-r--r-- 1 arika staff 11 12 13 21:38 README.md
-rw-r--r-- 1 arika staff 136 12 13 21:38 admin.env
drwxr-xr-x 4 arika staff 136 12 13 21:38 back
drwxr-xr-x 3 arika staff 102 12 13 21:38 cloudformation
drwxr-xr-x 2 arika staff 68 12 13 21:38 plugins
-rw-r--r-- 1 arika staff 495 12 13 21:41 s-project.json
CloudFormationでIAMあたりを作っているっぽ。S3は別。
CloudFormationのテンプレートが自動生成されて、そこにIAMのロールやらの定義が書かれている。
んで、おそらくここにAWS elsaticsearchの設定とかを書いておいてserverless resources deploy
ってやるとデプロイされる、とかができるための仕組みだと思う。
AWSのリソースの管理もできるということですね。素晴らしい。
モジュールとかファンクションとかを作る
$ serverless module create -m greetings -f hello
Serverless: Successfully created hello function.
Serverless: Installing "serverless-helpers" for this module via NPM...
serverless-helpers-js@0.0.3 node_modules/serverless-helpers-js
└── dotenv@1.2.0
Serverless: Successfully created new serverless module "greetings" with its first function "hello"
$ ls -l back/modules/greetings/
total 16
drwxr-xr-x 5 arika staff 170 12 13 21:49 hello
drwxr-xr-x 3 arika staff 102 12 13 21:49 lib
drwxr-xr-x 3 arika staff 102 12 13 21:49 node_modules
drwxr-xr-x 2 arika staff 68 12 13 21:49 package
-rw-r--r-- 1 arika staff 359 12 13 21:49 package.json
-rw-r--r-- 1 arika staff 277 12 13 21:49 s-module.json
backっていうディレクトリの下にhelloっていうのができて、
そこのhandler.jsってやつがメイン処理っぽい。。。?
'use strict';
/**
* Serverless Module: Lambda Handler
* - Your lambda functions should be a thin wrapper around your own separate
* modules, to keep your code testable, reusable and AWS independent
* - 'serverless-helpers-js' module is required for Serverless ENV var support. Hopefully, AWS will add ENV support to Lambda soon :)
*/
// Require Serverless ENV vars
var ServerlessHelpers = require('serverless-helpers-js').loadEnv();
// Require Logic
var lib = require('../lib');
// Lambda Handler
module.exports.handler = function(event, context) {
lib.respond(event, function(error, response) {
return context.done(error, response);
});
};
...いや、こっちか?でもlibの下にメイン処理があるもんか?
おそらくhandlerはいじらずここだけ意識していじればいいぜって感じか?
/**
* Lib
*/
module.exports.respond = function(event, cb) {
var response = {
message: "Your Serverless function ran successfully!"
};
return cb(null, response);
};
lambdaへのデプロイ
$ serverless function deploy
Serverless: Deploying functions in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed functions in "development" to the following regions: ap-northeast-1
api gatewayへのデプロイ
$ serverless endpoint deploy
Serverless: Deploying endpoints in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed endpoints in "development" to the following regions:
Serverless: ap-northeast-1 ------------------------
Serverless: GET - https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/development/greetings/hello
ローカルでのテスト
ローカルでのテストも簡単にできるのは素晴らしい。
$ serverless function run
Serverless: Running GreetingsHello...
Serverless: -----------------
Serverless: Success! - This Response Was Returned:
Serverless: {"message":"Your Serverless function ran successfully!"}
リンク集
http://docs.serverless.com/v0/docs
http://qiita.com/mokemokechicken/items/f81c886053f7d81a655d
elasticsearch勉強会
elasticsearch勉強会
percolatorのユースケース
アラート
インデックスが特定のクエリにマッチしたら教えてくれ。広告出稿する場合
ユーザがサイト検索する
アパートを検索して結果を表示するが
新しいマッチする物件が出たら知りたい
どのメールに通知すればいいのかみたいなのを取得して通知することができる分類
ニュースサイトやブログがあってカテゴリわされている
カテゴリは検索として表現できる
ニュースに地域などの属性があれば東京のニュース一覧とかできる
どの記事がどの地域に属するかというのを設定するにはどうしたら良いか
percolation queryを使えばどの記事がどの地域に属するかということを簡単に設定できる。
記事をかいてpercolationを使えばその記事のカテゴリを得られるgroclassificationについて
例えば緯度経度を使って検索することもできるけど検索はめんどい
percolationを使ってこのお地域はどの地域内にあるみたいなことも。言語の検出にも使える
日本語は簡単だけどラテン語なんかは難しい
特定の言語固有の単語などもあるのでこの言語にしかない単語をpercolationクエリとして
設定しておけば言語判別できるpercolatorにはメタデータを設定できる
いつそのクエリが保存されたのかなどなど
課金している人にのみ通知したい場合、課金しているかという情報もメタデータになる
そのメタデータによって通知の頻度を変えるとかもできるハイライトをできる
特定のトピックについて通知をしてもらいたい場合
トピックをpercolatorとして保存しておいて結果をハイライトできる
これが reverse search
esとRDBMSを検索するのはどう違うか
単にマッチするかどうかだけでなく、関連性も検出できる
TF-IDF
TF term frequency : 単語の出現頻度、頻度により関連性を調べられる。
IDF : どれくらいドキュメント内でレアかどうか
例えばisとかtheとか検索してもほぼ全部のドキュメントに出てくるので
あんまり関連性の重要性には寄与しない。
luceneはTF-IDF以外にもフィールドの長さを加味する
東京の本で東京について検索した場合たくさんヒットするけど
その中のタイトルでヒットすれば関連性が高いと言える
function scoreという機能を使えばドキュメント自体に
格納されていない情報も検索のタイミングでスコア算出につかうことができる
映画を検索した場合、映画のレビュー情報も算出できる。
レビューの星の数だけでソートしないほうがいいですね?
それだけでランクが決まってしまうので。
でも少しだけ順序に入れると良い。。
ホテルを検索する例
grand hotelというホテルを検索
指定した地点から1km以内がいいと指定した場合、1km以内であれば完全にマッチとするけど
そこから離れていても検査くっかに入れる
バルコニーが欲しいと指定した場合、バルコニーがなくても検索結果に入れる
でもバルコニーがあればより検索結果の上位に出すようにする
populartyというフィールド(レビュー)もランクに加味する
さらに幾分ランダムも入れる。つど発見があるように。
これらのウェイトはチューニング可能。
esは単語の頻度だけではなくいろんな情報を持っている。
aggregationについて
facetsともいう。
githubの検索結果の左側のようなやつ。
検索結果の中から検出したものでオーバービュートなる(どの言語がどれくらいあるかとか)
esを使うことで多次元の情報を見ることができる。
グラフ化するだけならRDBMSでもでk里う。
レコメンデーション
音楽について、特定のアーティストをlikeしているかどうか。
誰がどのアーティストをlikeしているのかという情報を格納する。
レコメンドする方法としてアーティストを検索して
さらにアーティストをlikeしている人を算出。
でも人気は必ずしも寒冷生徒はなりません。
termsでaggregateする代わりにsignificant term というものを使う。
これはaggregationの一種で単に人気があるということだけでなく、
特定のグループ内で突出しているものを調べられる。
アーティストを、誰が、likeしているのかという情報持っているし、
転値インデックスもあるので検出できる。
バンドをlikeした人数と、その検索termでlikeした人数を比較すれば
突出したものを検知することができる。sampler aggregation es2.0の新機能
例えば1ユーザにつき1ドキュメントだけ、とかできる。
1ユーザが何百ドキュメントを持っている場合効率的。
自分と同じものをよりたくさんlikeしている人は近い傾向を持っているとわかる。
誰もが好きなバンドをlikeしているというのはあまり参考にならないが
レアなバンドであれば大変好みが近いと言える(TF-IDFの応用)
sampler aggregationを使えばより効率的に、すばやくレコメンデーションできる。wikipediaの記事をグラフ化した場合、各記事同士がたくさんリンクしている。
共通のコネクションが大事。
たくさん調べればスーパーノード(共通してリンクしているノード、記事)がわかる
でも、人名が人物とリンクしているという情報なんかは意味があまりない。カンファレンスで、どのwebサイトによく行きますか?と聞いたら
githubとかstackoverflowと答えが出るでしょう。
googleではなく、これがカンファレンス特有の答えです。人間が、世の中をどういう風に見ているのかと同じ考え方。
データを期間で区切って調べる(週とか時間とかで)
signficant term を調べたら何が得られるか?例えばハッシュタグで。
その日で他の人に比べてたくさん使われているハッシュタグがわかる。
トレンドがわかる。
情報は力です。esを使えばよりたくさんの情報が得られる。