the industrial

ブログと言うより自分のためのメモ以外の何モノでもないです。でも読んでくださってありがとうございます。

幸せの1ページ

幸せの1ページ [DVD]

 

ジェラルド・バトラーと、ジョディー・フォスターと、アビゲイル・ブレスリン

 

子役のアビゲイル・ブレスリンちゃんは、どーっかで観たことあるのだけど思い出せなくて、調べてみると、なんとメル・ギブソン主演のサインのボーという女の子役の子だった!

 

ボーちゃんはすっごく可愛かったなあ。

 

ジョディー・フォスターは相変わらず綺麗なのだけど、もういくつになるんだろうかね。

 

映画の内容自体は、なんというか終始突拍子もないし、まったく意味のない事ばかりなのだけど、爽やかに感動出来て癒される、なかなかの良作だった。

 

娘ちゃんが結婚するときに踏みたくない38のステップ

今話題のさえりさんの妄想がすごく面白かったのだけど、妄想だったら僕も負けないので、久しぶりに妄想ブログを書いてみようと思う。

omiend.hatenablog.jp

omiend.hatenablog.jp

僕の妄想は、お父さんならば誰しもが妄想する「娘ちゃんが彼氏を連れてきた時から結婚式までの妄想」。

ちなみに、しこたま仕事でプログラムを書いて疲れた帰りの電車の中でコレを書いている関係上、ステップは71も無いのはご愛嬌。

ステップ1

娘ちゃんは世界中を飛び回るCA26歳になっているハズ。

ステップ2

生まれた時は助産師さんに「小ぶりですが元気ですよ」なんて言われていたのだが、母親に似たのか足がスラッとしていて、父親の僕が言うのも何だがなかなかの美人になっているハズ。

ステップ3

最近仕事が忙しいのか土日も家に居ないなあと思っていたら、「お父さん、今度あってもらいたい人がいるんだけど」と言い出すハズ。

ステップ4

「嫌だ」とも言える訳はなく、仕方なしに「分かった、今度の日曜日に連れて来なさい」と言うのだが、内心は歯をくいしばるほど恐怖におののいているハズ。

ステップ5

日曜日が怖くてしばらく仕事がおっつかないハズ。

ステップ6

土曜日の夜は眠れないハズ。

ステップ7

いざ、日曜日の朝、全く眠れなかったのに早起きしているハズ。

ステップ8

何故か自分の書斎を掃除しだすハズ。

ステップ9

そんなソワソワ落ち着きのない僕を見て嫁ちゃんはニヤニヤしているハズ。

ステップ10

そんなとき、娘ちゃん「ただいまー」彼氏くん「お、おじゃまします!」嫁ちゃん「いらっしゃい。」とか言う声が聴こえるハズ。

ステップ11

嫁ちゃん「あらあら綾野くん、またパーマかけたの?今度もふわふわでよく似あってるわね、このイケメーン」とか言う声が聞こえ、そこで初めて彼氏くんは僕の嫁ちゃんは既に面識があるのがわかるハズ。

ステップ12

ちょっと疎外感を感じるハズ。

ステップ13

娘ちゃん「ちょっと綾野くんは私の彼氏なんだからね!」とか言う声も聞こえて、なんとも言えない喪失感を感じるハズ。

ステップ14

いざ彼氏くんと対面すると、男からしてもイケメンだと思ってしまうハズ。

ステップ15

綾野くん「お父さん、はじめまして、娘ちゃんさんとお付き合いさせていただいております綾野ともうします!」などといきなり「お父さん」呼ばわりされ、ちょっとムッと来るハズ。

ステップ16

でもおみやげに僕が好きなお酒を渡してくれて、さらに話して見ると割りと好青年だと感じてしまうハズ。

ステップ17

綾野くんは誰もが知っている検索エンジンで有名な外資系一流企業で働いているハズ。

ステップ18

その企業の平均年収をこっそり調べてみると、どうやら僕が綾野くんと同じ年齢の時にもらっていた年収の6倍はあるであろうハズ。

ステップ19

僕は綾野くんに全てにおいて負けを実感してしまうハズ。

ステップ20

「ふ、二人はどこで知り合ったのかな?」と聞くと、「共通の友人の紹介で...」と変に濁されるハズ。

ステップ21

そんなこんなで、普通に家に遊びに来るようになって早2年が過ぎるハズ。

ステップ22

ある日、珍しくスーツ姿で家に来た綾野くんが神妙な面持ちをし、「お父さん、今日はお願いがあって来ました」と始めるハズ。

ステップ23

綾野くん「お父さん、お母さん、娘ちゃんさんを僕に、僕に下さい!娘ちゃんさんと結婚させて下さい!」と言い始めるハズ。

ステップ24

一瞬何が起きたのかわからず、何故か東野圭吾の「秘密」を思い出すハズ。

ステップ25

綾野くんに「とりあえず二発殴らせろ」とか言っちゃうハズ。

ステップ26

ソレを聞いた嫁ちゃんに、割りと本気で怒られるハズ。

ステップ27

怒られて割れに帰った僕が、「分かった、娘ちゃんの事をよろしくな」と、案外アッサリ言っちゃうハズ。

ステップ28

綾野くんが帰った後、案外アッサリ認めちゃったのを後悔するハズ。

ステップ29

しばらくすると結婚式の準備で忙しいのかなかなか二人が遊びに来なくなり、少しつまらない自分に気づくハズ。

ステップ30

いざ結婚式当日、少し寝坊するハズ。

ステップ31

いよいよ挙式。ウェディングドレスに身を包んだ娘ちゃんを観た瞬間、とりあえず涙ぐむハズ。

ステップ32

そして生まれてから今までの思い出が止めどなく涙と一緒にあふれでてくるハズ。

ステップ33

気が付くと挙式が終わっているハズ。

ステップ34

夢にまで観たヴァージンロードを娘ちゃんと歩く瞬間を全く覚えて居ないハズ。

ステップ35

ひとしきり披露宴が終わり、娘ちゃんから僕の嫁ちゃんへの手紙で何故か僕が涙腺崩壊するハズ。

ステップ36

僕への言葉は茶目っ気たっぷりの何かなハズ。

ステップ37

そして家に帰り、嫁ちゃんと二人で娘ちゃんが生まれた時の写真を観て、号泣するハズ。

ステップ38

でも、何よりも娘が幸せならばそれで良いと思う。

...ハズ。

書いてみたけどかなり内容のない内容になってしまった。

ちなみに僕の娘ちゃんは今1歳半なので、あと25年は安泰。

やっぱ文章を書く仕事をしている人の文章って面白いねー!

【結婚したい】年下彼氏と結婚するまでに踏みたい理想のステップ71

wedding.mynavi.jp

「結婚式」の求人 jp.stanby.com

プレシャス

プレシャス [DVD]


33歳の誕生日には何か映画観たいなと思い、U-NEXTで鑑賞。U-NEXTだけなのかは分からないのだけど、途中で止まったりして非常にストレスフル。

そしてこの映画自体も非常にストレスフルな映画。

映画自体の出来はかなり良いのだけど、もうストーリーが救われなさすぎてツライ。

ここまで観ててツライ映画はなかなかなく、それだけこの映画が訴える事が上手く映画として表現されているのだという事。

主人公の女の子は、16歳、肥満、黒人。いわゆる貧困層で暮らしており、母親と生活保護を受けて暮らしている。

それだけならまだ救いはあるのだけど、とにかくこの主人公の身に降りかかる理不尽な出来事の理不尽さ。胸を締め付けられるのではなく、引き裂かれる想いにさせられる。

そんな中にも少しだけ、本当に少しだけ暖かい心になれる場所があるのがせめてもの救いか…。

本当にツライのでおいそれとオススメは出来ないのだけど、今のところ今年観た映画でNo.1。

Elasticsearch入門してます (5日目) とっとこAggregations

まごまごせんと、とりあえず1回Aggregations試そうぜ!ということで、今日はAggregations周りしかやらない。

Elasticsearchの本当にすごいところってたぶんlucene由来の全文検索なんだと思っているのだけど、そこまでたどり着いていない僕がゴイスーと思ってElasticsearchにハマりだしたのが、このAggregationsの機能。

なんというか、SQLを超えるほどの柔軟なクエリーが書けるのではないかと思ったのがElasticsearchのクエリーで、そんなElasticsearchのクエリーの真髄と言っても過言ではない(個人調べ)のが、その名の通り基本的に集計を行うためのAggregationsというもの。

Aggregations

公文はオフィシャルサイトから転記(いいのかな)しちゃうのだけど、こんな感じ。

"aggregations" : {
    "<aggregation_name>" : {
        "<aggregation_type>" : {
            <aggregation_body>
        }
        [,"meta" : {  [<meta_data_body>] } ]?
        [,"aggregations" : { [<sub_aggregation>]+ } ]?
    }
    [,"<aggregation_name_2>" : { ... } ]*
}

Aggregationsの中にさらにAggregationsを記述することが出来るのが地味に便利そう。さらに、1回のクエリーで2個以上のAggregationsを記述することができる。

さてさて、Aggregationsは基本的にBucketingMetricPipelineという3種類のタイプがあるらしい。

今日はその中でも基本っぽい?Bucketing Aggregationsの中を見ていきたい。

Index

前回作ったIndex定義の中で、nameに入っているデータがバリエーション豊かなので、nameにもTermが効くように"index": "not_analyzed"を付けておいた。

(この辺りはあとでちゃんとキャッチアップしなきゃという焦り)

{
  "mappings": {
    "type-a": {
      "dynamic": "strict",
      "_source": {
        "enabled": true
      },
      "_all": {
        "enabled": false
      },
      "_ttl": {
        "enabled": false
      },
      "properties": {
        "name": {
          "type": "string",
          "index": "not_analyzed"
        },
        "attribute": {
          "type": "string",
          "index": "not_analyzed"
        },
        "period": {
          "type": "object",
          "properties": {
            "startDate": {
              "type": "date",
              "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
            },
            "endDate": {
              "type": "date",
              "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
            }
          }
        },
        "createdDate": {
          "type": "date",
          "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
        },
        "updatedDate": {
          "type": "date",
          "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
        }
      }
    },
    "type-b": {
      "dynamic": "strict",
      "_source": {
        "enabled": true
      },
      "_all": {
        "enabled": false
      },
      "_ttl": {
        "enabled": false
      },
      "properties": {
        "name": {
          "type": "string",
          "index": "not_analyzed"
        },
        "attribute": {
          "type": "string",
          "index": "not_analyzed"
        },
        "period": {
          "type": "object",
          "properties": {
            "startDate": {
              "type": "date",
              "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
            },
            "endDate": {
              "type": "date",
              "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
            }
          }
        },
        "createdDate": {
          "type": "date",
          "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
        },
        "updatedDate": {
          "type": "date",
          "format": "YYYY-MM-dd'T'HH:mm:ss.SSSZ"
        }
      }
    }
  }
}

テストデータ

前回は計2万行のデータを入れてみたのだけど、2万行も要らないし、しかもデータのバリエーションとして大したものがなかったので、ちょっと作りなおしてみた。

1月は1件、2月は2件...と、それぞれの月でその月と同じ数のデータがあり、データのCreatedDateをそれぞれの月に属させている。

https://goo.gl/sYlG1m

Bucketing

Bucket Aggregations

さらにいろいろなAggregationsがあるのだけど、Filter Aggregationsから見てみる。

Filter Aggregations

Filter Aggregation

これはとてもわかりやすひ。

AggregationsもやはりSearch APIに載せるので(たぶん)、CURLでやるとこんなクエリーになる。

$ curl -XGET 'localhost:9200/index-a/_search?pretty' -d '{
  "aggregations" : {
    "my_count_aggs" : {
      "filter" : {
        "term" : { "name": "NAME10001" }
      }
    }
  }
}'

結果こうなる。

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 156,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10005",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10005", "attribute" : "ATTR10005", "period" : { "startDate": "2015-03-08T15:00:00.000Z", "endDate": "2015-03-09T14:59:59.999Z" } , "createdDate" : "2015-03-08T15:00:00.000Z", "updatedDate" : "2015-03-08T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10014",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10014", "attribute" : "ATTR10014", "period" : { "startDate": "2015-05-22T15:00:00.000Z", "endDate": "2015-05-23T14:59:59.999Z" } , "createdDate" : "2015-05-22T15:00:00.000Z", "updatedDate" : "2015-05-22T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10018",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10018", "attribute" : "ATTR10018", "period" : { "startDate": "2015-06-15T15:00:00.000Z", "endDate": "2015-06-16T14:59:59.999Z" } , "createdDate" : "2015-06-15T15:00:00.000Z", "updatedDate" : "2015-06-15T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10020",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10020", "attribute" : "ATTR10020", "period" : { "startDate": "2015-06-29T15:00:00.000Z", "endDate": "2015-06-30T15:59:59.999Z" } , "createdDate" : "2015-06-29T15:00:00.000Z", "updatedDate" : "2015-06-29T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10029",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10029", "attribute" : "ATTR10009", "period" : { "startDate": "2015-08-01T15:00:00.000Z", "endDate": "2015-08-02T14:59:59.999Z" } , "createdDate" : "2015-08-01T15:00:00.000Z", "updatedDate" : "2015-08-01T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10039",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10039", "attribute" : "ATTR10019", "period" : { "startDate": "2015-09-15T15:00:00.000Z", "endDate": "2015-09-16T14:59:59.999Z" } , "createdDate" : "2015-09-15T15:00:00.000Z", "updatedDate" : "2015-09-15T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10047",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10047", "attribute" : "ATTR10007", "period" : { "startDate": "2015-10-08T15:00:00.000Z", "endDate": "2015-10-09T14:59:59.999Z" } , "createdDate" : "2015-10-08T15:00:00.000Z", "updatedDate" : "2015-10-08T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10063",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10063", "attribute" : "ATTR10003", "period" : { "startDate": "2015-11-15T15:00:00.000Z", "endDate": "2015-11-16T14:59:59.999Z" } , "createdDate" : "2015-11-15T15:00:00.000Z", "updatedDate" : "2015-11-15T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10067",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10067", "attribute" : "ATTR10007", "period" : { "startDate": "2015-12-01T15:00:00.000Z", "endDate": "2015-12-02T14:59:59.999Z" } , "createdDate" : "2015-12-01T15:00:00.000Z", "updatedDate" : "2015-12-01T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10073",
      "_score" : 1.0,
      "_source":{ "name" : "NAME10073", "attribute" : "ATTR10013", "period" : { "startDate": "2015-12-08T15:00:00.000Z", "endDate": "2015-12-09T14:59:59.999Z" } , "createdDate" : "2015-12-08T15:00:00.000Z", "updatedDate" : "2015-12-08T15:00:00.000Z" }
    } ]
  },
  "aggregations" : {
    "my_count_aggs" : {
      "doc_count" : 1
    }
  }
}

Search APIの検索条件にヒットしたデータ(上の例では条件指定なし)と、aggregationsで指定した条件に合致するデータ件数が、"aggregations"."{指定した名前}"."doc_count"という名前で帰ってくる。

Search APIでデータを絞った後に、Aggregationsを行う場合はこんな感じか。

2014年と2015年それぞれの12月の中で、"attribute:":"ATTR10008"のデータが何件存在するかを数える例。

$ curl -XGET 'localhost:9200/_search?pretty' -d '{
  "query" : {
    "or" : {
      "filters" : [ {
        "range" : {
          "createdDate" : {
            "gte" : "2014-12-01",
            "lte" : "2015-01-01",
            "format": "yyyy-MM-dd||yyyy-MM-dd"
          }
        }
      }, {
        "range" : {
          "createdDate" : {
            "gte" : "2015-12-01",
            "lte" : "2016-01-01",
            "format": "yyyy-MM-dd||yyyy-MM-dd"
          }
        }
      } ]
    }
  },
  "aggs" : {
    "my_count_aggs" : {
      "filter" : {
        "term" : { "attribute": "ATTR10008" }
      }
    }
  }
}'

結果。

{
  "took" : 27,
  "timed_out" : false,
  "_shards" : {
    "total" : 10,
    "successful" : 10,
    "failed" : 0
  },
  "hits" : {
    "total" : 36,
    "max_score" : 0.35355338,
    "hits" : [ {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10067",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME10067", "attribute" : "ATTR10007", "period" : { "startDate": "2015-12-01T15:00:00.000Z", "endDate": "2015-12-02T14:59:59.999Z" } , "createdDate" : "2015-12-01T15:00:00.000Z", "updatedDate" : "2015-12-01T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-a",
      "_id" : "10073",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME10073", "attribute" : "ATTR10013", "period" : { "startDate": "2015-12-08T15:00:00.000Z", "endDate": "2015-12-09T14:59:59.999Z" } , "createdDate" : "2015-12-08T15:00:00.000Z", "updatedDate" : "2015-12-08T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-b",
      "_id" : "20069",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20069", "attribute" : "ATTR10009", "period" : { "startDate": "2014-12-15T15:00:00.000Z", "endDate": "2014-12-16T14:59:59.999Z" } , "createdDate" : "2014-12-15T15:00:00.000Z", "updatedDate" : "2014-12-15T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-b",
      "_id" : "20072",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20072", "attribute" : "ATTR10012", "period" : { "startDate": "2014-12-01T15:00:00.000Z", "endDate": "2014-12-02T14:59:59.999Z" } , "createdDate" : "2014-12-01T15:00:00.000Z", "updatedDate" : "2014-12-01T15:00:00.000Z" }
    }, {
      "_index" : "index-b",
      "_type" : "type-b",
      "_id" : "20069",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20069", "attribute" : "ATTR10009", "period" : { "startDate": "2014-12-15T15:00:00.000Z", "endDate": "2014-12-16T14:59:59.999Z" } , "createdDate" : "2014-12-15T15:00:00.000Z", "updatedDate" : "2014-12-15T15:00:00.000Z" }
    }, {
      "_index" : "index-b",
      "_type" : "type-b",
      "_id" : "20072",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20072", "attribute" : "ATTR10012", "period" : { "startDate": "2014-12-01T15:00:00.000Z", "endDate": "2014-12-02T14:59:59.999Z" } , "createdDate" : "2014-12-01T15:00:00.000Z", "updatedDate" : "2014-12-01T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-b",
      "_id" : "20068",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20068", "attribute" : "ATTR10008", "period" : { "startDate": "2014-12-08T15:00:00.000Z", "endDate": "2014-12-09T14:59:59.999Z" } , "createdDate" : "2014-12-08T15:00:00.000Z", "updatedDate" : "2014-12-08T15:00:00.000Z" }
    }, {
      "_index" : "index-a",
      "_type" : "type-b",
      "_id" : "20073",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20073", "attribute" : "ATTR10013", "period" : { "startDate": "2014-12-08T15:00:00.000Z", "endDate": "2014-12-09T14:59:59.999Z" } , "createdDate" : "2014-12-08T15:00:00.000Z", "updatedDate" : "2014-12-08T15:00:00.000Z" }
    }, {
      "_index" : "index-b",
      "_type" : "type-b",
      "_id" : "20068",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20068", "attribute" : "ATTR10008", "period" : { "startDate": "2014-12-08T15:00:00.000Z", "endDate": "2014-12-09T14:59:59.999Z" } , "createdDate" : "2014-12-08T15:00:00.000Z", "updatedDate" : "2014-12-08T15:00:00.000Z" }
    }, {
      "_index" : "index-b",
      "_type" : "type-b",
      "_id" : "20073",
      "_score" : 0.35355338,
      "_source":{ "name" : "NAME20073", "attribute" : "ATTR10013", "period" : { "startDate": "2014-12-08T15:00:00.000Z", "endDate": "2014-12-09T14:59:59.999Z" } , "createdDate" : "2014-12-08T15:00:00.000Z", "updatedDate" : "2014-12-08T15:00:00.000Z" }
    } ]
  },
  "aggregations" : {
    "my_count_aggs" : {
      "doc_count" : 2
    }
  }
}

ワーオ!柔軟!

"aggregations""aggs"(卵達?)でも良い。

curl -XGET 'localhost:9200/index-a/_search?pretty' -d '{
  "aggs" : {
    "my_count_aggs" : {
      "filter" : {
        "term" : { "name": "NAME00001" }
      }
    }
  }
}'

これは別件かもしれないのだけど、リクエストパラメータにsearch_type=countとつけると、hitsの中身が省略される。(データ転送量が減るのが良い?)

$ curl -XGET 'localhost:9200/_search?search_type=count&pretty' -d '{
  "query" : {
    "or" : {
      "filters" : [ {
        "range" : {
          "createdDate" : {
            "gte" : "2014-12-01",
            "lte" : "2015-01-01",
            "format": "yyyy-MM-dd||yyyy-MM-dd"
          }
        }
      }, {
        "range" : {
          "createdDate" : {
            "gte" : "2015-12-01",
            "lte" : "2016-01-01",
            "format": "yyyy-MM-dd||yyyy-MM-dd"
          }
        }
      } ]
    }
  },
  "aggs" : {
    "my_count_aggs" : {
      "filter" : {
        "term" : { "attribute": "ATTR10008" }
      }
    }
  }
}'
{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 10,
    "successful" : 10,
    "failed" : 0
  },
  "hits" : {
    "total" : 36,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_count_aggs" : {
      "doc_count" : 2
    }
  }
}

Aggregationsのfiterを使えば、OR条件で指定した値ごとにカウントができる。

$ curl -XGET 'localhost:9200/index-a/_search?search_type=count&pretty' -d '{
  "aggregations" : {
    "my_count_aggs" : {
      "filter" : {
        "or" : {
          "filters" : [ {
            "term" : { "attribute" : "ATTR10001" }
          }, {
            "term" : { "attribute" : "ATTR10002" }
          }, {
            "term" : { "attribute" : "ATTR10003" }
          } ]
        }
      },
      "aggs" : {
        "by_term" : {
          "terms" : { "field" : "attribute" }
        }
      }
    }
  }
}'
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 156,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_count_aggs" : {
      "doc_count" : 24,
      "by_term" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [ {
          "key" : "ATTR10001",
          "doc_count" : 8
        }, {
          "key" : "ATTR10002",
          "doc_count" : 8
        }, {
          "key" : "ATTR10003",
          "doc_count" : 8
        } ]
      }
    }
  }
}

次は、仕事でdate_histogramをネストさせてた面白いAggregationsが出来たので、そこらへんをやるべし。

Elasticsearch入門してます (4日目) しょぼいPRで名前を残した話と勉強会に参加した話

f:id:omiend:20160108155150p:plain

タイトル通り、僕がElasticさんに送ったPullRequestがマージされたお話。

とはいっても、内容は保育園児でも出来そうなちょーしょぼいものなのでなんの自慢にもならないのだけど、PRを送る方法は決められた手順をもってやっているので、一応書き残しておこうかなと。

肝心の修正内容は、"を1個追加するだけという、もう本当恥ずかしいくらいしょぼいものなのだけど、ソレ以上に余りある栄誉(Elasticsearchのプロダクトに名前が残るという自己満足)を頂けて光栄の極みにございます。

github.com

何を直したのかというと、とりあえずこのISSUEを見てもらえば。

github.com

ElasticsearchのオフィシャルサイトにあるDocumentationを読み漁っていたら、クエリの例文で " が抜けている箇所があったので、「よっしゃPullRequest送ってElasticsearchにomiendの名前残したろ!」と。

しかし、いきなりPRを送るのはいくらなんでも失礼なので、まずはContributingを読みましょう。

github.com

ここで要求されていることは、簡単に言うと...

  1. もしバグを見つけたら、Issueに上がってないか調べてね
  2. 修正するときはForkしてね
  3. テストしておいてね
  4. Contributor License Agreementにサインしておいてね

Contributor Agreement | Elastic

  1. OKだったらPR送ってね!

って感じかな?

僕はそんなに英語できる人間ではないので、良いか悪いかは別として変な誤解を生まないためにも、Elasticの方との文章でのやり取りは極力少なくしたかったんだよね。

なので、どういった内容のIssueで、どういった形が本来望ましいのか(つまり英語で言うとShould を使うのかなと)、そしてどういう修正内容を予定しているかをプログラムレベルで記載してみたのだ。

そう書いておけば、たとえ英語がヘタで文法が間違っていても、少なからず何がしたいのかは通じるかなと。

整理すると、まずはIssueから作成。次に、PRと紐付け。後は単語でソレらしく...(ここが一番むつかしいw)という感じ。

特に英語が出来ない勢で一番むつかしいのが、「4. Contributor License Agreementにサイン」なのだけど...そこはGoogle翻訳片手に頑張るしか無いw

でもやっぱり英語が出来ないと、こういったこともやり方がスマートにならないですなあ。課題は英語だ。

まあ、以前も同じようにPlayframework(Typesafeさん)にPRしたことあるので、今回はそんなにドキドキしなかったデス。だから、興味がある人は1回やってみると良いかもですな!そうすればプロダクトはどんどん良くなる!...ハズ!

omiend.hatenablog.jp


そして、1月7日は #elasticsearchjp という勉強会に行ってきました。

東京駅前にあるリクルートさんのビルは初めてで、1Fの受付から41階にある会場までエレベーターを2個乗り継ぐ程のダンジョンさを体験。

学習のモッチベーション維持の為に効果的な方法の一つが、こういった勉強会への参加だったりするわけでして、まあ、内容は初学者の僕には難しいのだけど(基本的に機械学習のお話だったし)、懇親会ではトレジャーデータの @repeatedlyさんや、Elasticの@johtaniさんとお話出来て楽しかったデス。

スター・ウォーズ ジェダイの帰還(エピソード6)

スター・ウォーズ エピソード6 ジェダイの帰還 リミテッド・エディション [DVD]

新年なので、しばらくElasticsearchと映画ネタばかり書いてるかもしれません。

というか、このブログ自体もはやブログですらなく、ただの感想文になっている気がするのだけど、もともとは1日あったことを毎日書いて証を残すうんたらかんたら

というわけで、エピソード6を鑑賞(突然)。

ラストはちょっと涙涙の結末なのだけど、個人的にはダースベイダー卿にはとことん悪で居て欲しかった。

エピソード3でアレだけ子供を殺しまくったのに、最後自分の子供に改心させられるのは、狙ってなったことなのかどうか...いやはや深い。

今更気づいたのだけど、キングスマンに出てた教授役の人、ルーク・スカイウォーカーだったのね!

不思議な岬の物語

 

ふしぎな岬の物語 [Blu-ray]

 

テレビでやってたので、勉強しながら鑑賞。

 
言うなれば吉永小百合のプロモ映画って感じなのだろうか、演技は鬼気迫って凄いのだけど、内容が無いというかなんというか。
 
阿部寛は本当にナイスガイ笑
 
歳とったらこう言う映画も面白く感じるのだろうか。