2015年2月21日土曜日

英語がスランプ

タイトル通りです。

最近、英語がスランプです。
困っています。

なので、CNN Expressの暗唱をはじめています。
脱出するまで復習中心でやっていきます。スランプが終わると一気に伸びが実感できるのはわかっているんですが、わかっていてもこの時期は辛いです。

英語を使うのをさぼらないように、以下にメモ。

教材
CNN ENGLISH EXPRESS 2015年2月号

タイトル
Uneven in the Extreme

CDNO, シャドウイング回数, 暗唱回数, 暗唱時間
33, 43, 5, 0:26:48
34, 38, 5, 1:13:48
35, 30, 2, 0:53:76
36, 20, 0, 0:00:00
37, 15, 0, 0:00:00

タイトル
Finding a new Calling

CDNO, シャドウイング回数, 暗唱回数, 暗唱時間
50, 25, 1, 0:43:76
51, 24, 1, 1:04:00

この記事を読んでくれている人のために説明すると、
CD番号あたりのシャドウイングの回数と、暗唱した回数、1回あたりにかかった暗唱の時間を計測してます。
録音した暗唱は、聞いてどこが曖昧なのか、どこの部分が良くないのかを洗い出して修正して、発声して修正しています。

 上記はあくまで僕が試行錯誤して編み出した学習方法なのですが、そこそこ効果のある勉強方法だと思います。
 多くのトイッカー達が暗唱が一番効果あるといって、公式テキストヒアリングを暗唱してますが、同じことです。
 ただ、僕の英語の学習方法は、CNNのニュースや経営者や著名なエンジニアのプレゼンの暗唱が中心です。TOIECの教材の英語のほうが発音は綺麗なんですけど、僕には内容がつまらないし、飽きてしまって継続して続けるのが無理です。
 続かない語学学習ほど意味がないものはないので、僕は語学試験での高得点取得の勉強は切り捨てました。(今受ければ高得点かもしれませんが。。。)あくまで技術のため(仕事で使う)英語力を向上させるのが目標です。

ついでにいうと、暗唱をするなら発音をきちんと鍛えるのをオススメします。
僕はフォニックスの教材で毎日20分くらいやってます。
スポーツの選手でいうマラソンみたいなもので、あとあとすごく効いてきます。
あとは文法ですね。去年末に買った一億人の英文法(だったかな?)っていう本はすごく良くて、5回くらいは読んでます。

現状、そんな感じです。
最近は、かなり気分が落ち込んでいる状況であまりロクな更新ができなくてすいません。
そのうち、記事も既存のアプリも更新をかけていきたいと思います。

でわ。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月20日金曜日

Effective iphone application development. (効率的なiphoneアプリ開発)

shortcut command wins development.

Time is money. these tips is useful to reduce working hours.

enviroment(環境)

  • Xcode6.1

search class or function(クラスと関数を検索)

Cmd + Shift + O


    Cmd + Shift + O

Display property and functon(プロパティとメソッドを表示)


    Ctr + 6

At the same time, you should study pragma.

thank you.

参考

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

iphone app developes copy and paste. (コピペでiphoneアプリ開発)

frequently using code tips(実装時によく利用するコードのまとめ)

enviroment(環境)

  • Xcode6.1

UIViewController

screen transition(画面遷移)


    PointDisplayViewViewController * viewController = [[PointDisplayViewViewController alloc]init];
    [self presentViewController:viewController animated:YES  completion:nil];

setting backgroundImage(背景画像設定)


    UIImage *backgroundImage  = [UIImage imageNamed:@"bg_1.png"];
    self.view.backgroundColor = [UIColor colorWithPatternImage:backgroundImage];

Library(ライブラリ)

install cocoapods(cocoapodsのインストール)


    // change directory to project folder
    cd {project_folder}
    // make Gemfile
    touch Gemfile
    // open Gemfile
    vi Gemfile

    // write code
    source 'https://rubygems.org'
    gem 'cocoapods'

    // install
    bundle install --path=vendor/bundle

* if ".cocoapods/repos (Errno::ENOENT)" has occurred, try next steps.

  1. bundle exec pod setup
  2. bundle exec pod install

thank you.

参考

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

cocoapodsを利用するときのgitignore

enviroment(環境)

  • Xcode6.1

さて、iphoneアプリ開発のgitignoreを記載するときにコピペサイトを探してたのですが、でたらめな情報がネット上に広がっていて、Podfile.lockはgitignoreに記載して良いというとんでもない意見が多数派をしてている状況になっていてびっくりしました。

そんなわけないでしょ(白目)

Podfile.lockファイルはGemfile.lockやBerkshelf.lockと同じ類のファイルなので、gitignoreに含めてはいけません。コミットしてください。みんなrubyやろうぜ!!(適当)

なぜかというと、これらのlockファイルにはどのバージョンのライブラリを導入したかという情報が書き込まれています。
なので、このファイルを消してしまうと、他の開発者がバージョン管理からソースコードをもってきてライブラリをDLしても、バージョンに差異がでてしまう可能性が高くなります。なので、絶対に消してはいけません。

installとupdateの違い

ついでにもう一点。これらのライブラリ管理ツールを使うと、updateとinstallコマンドで簡単にライブラリを追加できます。
大変便利なのですが、ネット上の情報だとupdateとinstallコマンドどっちでもOKです(ハート)という意見が多いです。

そんなわけないやろ(2回目)

installコマンドは、.lockファイルを参照し、指定されたバージョンのライブラリをインストールします。
updateコマンドは、.lockファイルを無視して、fileに記載されたライブラリを更新します。そして、更新時に.lockファイルを更新します。

ruby歴が長い人には当たり前のことなのですが、今は便利系ツールがrubyで作成されることが多くなっていて、最近利用する人が増えたため、知らない人が多いようですね。

ドキュメントにはしっかり目を通しましょう。
ああ、このブログだって結構適当ですからねw
間違ってたらすいません。

以上。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月15日日曜日

今後を考える

タイトル通りです。最近はいい加減、自分のダメ男加減にあきれてきてるので、意識的に脱出していこうと考えています。

今、ちょっと私生活で色々な新しい習慣を取り入れ始めています。 新学期がはじまる季節には、具体的な数値に落としこんで、こういうふうに自分自身を改善していくよと報告できればいいかなと考えています。

今年読んだ本は今のところ12冊です。んー、一年で100冊微妙w
あまり冊数が進んでいないのは、英語の学習に相当の時間をとられているのが原因です。 まあ、そのうち英語の勉強も飽きるだろうと踏んでいるのですがw(このへんのいい加減な性格がよくないですね) 

とはいえ、英語は、今後のダメ男脱出計画のコアな部分になる予定ではあります。

そんなわけで現状報告でした。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月8日日曜日

rails4 Springでテストの高速化

技術的な負債はこまめに返していきましょう。

テストの数が増えてきたので、Springを導入します。

環境

  • rails4.1.2 & centos6.5

springを導入


vi Gemfile

group :development, :test do
  gem 'spring-commands-rspec'
  gem 'rspec-rails'
end

// install
bundle install

bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rspec: generated with spring
* bin/rails: spring inserted

springの動作確認


bin/spring status
Spring is not running.

まだspringは動いていません。テストを実行します。


// いつものテスト実行コマンド
bundle exec rake spec

// springを入れた今回のテスト実行コマンド
bin/rspec -fd spec/*

Finished in 1 minute 5.06 seconds (files took 58.11 seconds to load)

一回目の時間は同じです。springの動作を確認してみます。


bin/spring status
Spring is running:

28728 spring server | test | started 6 mins ago                                                                                                                                 
28733 spring app    | test | started 6 mins ago | test mode

springが動いているのが確認できます。さて、二度目のテストを実行させてみましょう。


bin/rspec -fd spec/*

Finished in 53.92 seconds (files took 54.05 seconds to load)

多少は、ましになりましたね。とはいえ、まだまだ遅いです。次はGuardを入れようと思います。

以上

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

rails4 centos6.5でcapybaraを動かす

技術的な負債はこまめに返していきましょう。

というわけで、二か月以上放置していたcapybara webkitを導入し、動作させます。

環境

  • rails4.1.2 & centos6.5

bundle install

いきなり以下のエラーが発生


vi Gemfile

group :test do
  gem "database_cleaner", ">= 0.9.1"
  gem "email_spec", ">= 1.4.0"
  # gem "cucumber-rails", ">= 1.3.0", :require => false featureファイルのこと。わかりにくいので不要。capybaraだけで記載
  # gem "launchy", ">= 2.1.2", :group => :test
  gem "capybara", ">= 2.0.1", :group => :test
  gem 'simplecov'
  gem 'simplecov-rcov' # JenkinsのRuby metrics plugin用
end

// 実行
bundle install

qmake -spec linux-g++ ' not available

原因はcapybara webkitを動作させるにはQtが必要だから。最初はchefで処理を実装しようかと考えたのですが、導入時間が長すぎてchefのCIに組み込んだら発狂するので手動でインストールします。
以下、導入手順です。


// 必要なyum
sudo yum install libxcb libxcb-devel xcb-util xcb-util-devel
sudo yum install flex bison gperf libicu-devel libxslt-devel ruby
sudo yum install libXrender-devel

// Qtのinstall
mkdir ~/Downloads
cd ~/Downloads
sudo yum install wget
wget http://download.qt-project.org/official_releases/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.tar.gz
tar xzvf qt-everywhere-opensource-src-4.8.6.tar.gz
cd qt-everywhere-opensource-src-4.8.6
./configure -opensource -nomake examples -nomake tests

// gmakeして導入
sudo gmake install
sudo ln -s /usr/local/Trolltech/Qt-4.8.6/bin/qmake /usr/bin/qmake

これで準備OK。
もう一度bundle installを実行します。


Using libv8 3.16.14.7
Using mysql2 0.3.17
Using tilt 1.4.1
Using sprockets 2.12.3
Using sprockets-rails 2.2.4
Using rails 4.1.2
Using raindrops 0.13.0
Using rdoc 4.2.0
Using ref 1.0.5
Using rspec-rails 3.2.0
Using sass 3.2.19
Using sass-rails 4.0.5
Using sdoc 0.4.1
Installing simplecov-html 0.8.0
Installing simplecov 0.9.1
Installing simplecov-rcov 0.2.3
Using spring 1.2.0
Using spring-commands-rspec 1.0.4
Using therubyracer 0.12.1
Using turbolinks 2.5.3
Using uglifier 2.7.0
Using unicorn 4.8.3
Your bundle is complete!
It was installed into ./vendor/bundler

成功です。以上。

centos7以降だと上記の手順は不要で、コマンド叩くだけのようです。早く移行しないと。。。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

ElasticSearch 実戦に向けた学習 その1 バックアップと復元

ElasticSearch導入のための学習とメモ

環境

  • vagrant1.7.2
  • centos6.5

さて、その1,その2,その3で検索の基礎は理解できたので、実戦投入に向けた学習に切り替えます。あとは走りながらPDCAを回していきます。

運用で最低限利用しないと行けないのは、これまでの知識に加えて、

  • バックアップ
  • バックアップデータの復元
  • ログ
  • ユーザー辞書(必須ではないかな)

です。というわけでまずはバックアップから。(ElasticSearchではバックアップのことをスナップショットと読んでいるので、以降「スナップショット」で統一)

Snapshot And Restore

まずはテストデータの登録


curl -XPUT 'http://192.168.33.19:9200/game/nintendo/1' -d '
{
    "gama_name" :  "mario brothers",
    "main_character_name" :   "marip",
    "price" : 5000
}
'

curl -XPUT 'http://192.168.33.19:9200/game/nintendo/2' -d '
{
    "gama_name" :  "zelda",
    "main_character_name" :   "Smith",
    "price" : 6000
}
'

curl -XPUT 'http://192.168.33.19:9200/game/nintendo/3' -d '
{
    "gama_name" :  "donkey kong",
    "main_character_name" : "donkey",
    "price" : 7000
}
'

// 検索
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}


データ登録が完了したら、スナップショットを作成します。

repositories

スナップショットの作成の前にrepositoryを作成します。


// snapshot用のフォルダを作成
mkdir -p /var/elastic_search/my_backup

// フォルダの権限をelastic_searchにする
sudo chown elasticsearch:elasticsearch /var/elastic_search/my_backup/

// repository登録する
curl -XPUT 'http://192.168.33.19:9200/_snapshot/my_backup' -d '{
    "type": "fs",
    "settings": {
        "location": "/var/elastic_search/my_backup",
        "compress": true
    }
}
'

// 結果
{"acknowledged":true}

上手くいったみたいですね。一応コマンドから確認してみましょう。


curl -XGET 'http://192.168.33.19:9200/_snapshot/my_backup?pretty'

// 結果
{
  "my_backup" : {
    "type" : "fs",
    "settings" : {
      "compress" : "true",
      "location" : "/var/elastic_search/my_backup"
    }
  }
}

リポジトリが作成できたので、スナップショットを作成します。が、その前に理解しておかないといけないスナップショットの仕様を以下にまとめ。

  • スナップショットはclusterの中の、一意な名称によって特定される。
  • http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1なら「my_backup」がリポジトリで「snapshot_1」がスナップショット。
  • index スナップショットを作成する過程で、Elasticsearchはリポジトリの中に保存されたindexファイルの一覧を分析する。そして、最後のスナップショットから変更、もしくは作成されたファイルだけを保存する。
  • スナップショットがリポジトリから削除された時、Elasticsearchはリポジトリがスナップショットを保存している場所の参照だけ削除する。つまり、スナップショット自体はその場に残っている。

スナップショットを作成


// 作成
curl -XPUT "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"

// 結果
{"snapshot":{"snapshot":"snapshot_1","indices":["game","test","megacorp"],"state":"SUCCESS","start_time":"2015-02-06T06:59:29.624Z","start_time_in_millis":1423205969624,"end_time":"2015-02-06T06:59:30.186Z","end_time_in_millis":1423205970186,"duration_in_millis":562,"failures":[],"shards":{"total":15,"failed":0,"successful":15}}}

全てのindexが保存されていますね。リクエストのjsonでスナップショットを作成したいindexだけを指定することもできます。

さて、スナップショットを作成したので、データを変更してみましょう。index[game]にデータを2件追加します。


// データ登録
curl -XPUT 'http://192.168.33.19:9200/game/nintendo/4' -d '
{
    "gama_name" :  "metoroido",
    "main_character_name" :   "Samusu",
    "price" : 7000
}
'

// データ登録
curl -XPUT 'http://192.168.33.19:9200/game/nintendo/5' -d '
{
    "gama_name" :  "pokemon",
    "main_character_name" :   "Pikachu",
    "price" : 8000
}
'

// 検索
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 5,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

3件から5件にデータが増えました。
次はバックアップデータの復元をしましょう。(ElasticSearchではバックアップデータの復元のことをリストアと読んでいるので、以降「リストア」で統一)


// リストア
curl -XPOST "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1/_restore" -d '{
    "indices": "game",
    "rename_pattern": "game",
    "rename_replacement": "game2"
}'

// 検索
curl -XGET 'http://192.168.33.19:9200/game2/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

rename_patternとrename_replacementを指定しないと"error":"SnapshotRestoreException[[my_backup:snapshot_1] cannot restore index [game] because it's openが発生した。なぜ同じ名前だとリストアができないのだろうか。

indexの一覧を確認する


// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "game" : { },
  "test" : { },
  "megacorp" : { },
  "game2" : { }
}


indexが増えています。indexが存在しているとリストアができないのかもしれない。indexを削除、リストアの順かな。


// game index削除
curl -XDELETE 'http://192.168.33.19:9200/game/'

// game2 index削除
curl -XDELETE 'http://192.168.33.19:9200/game2/'

// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "test" : { },
  "megacorp" : { }
}

// リストア
curl -XPOST "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1/_restore" -d '{
    "indices": "game"
}
'

// 結果
{"accepted":true}

// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "test" : { },
  "megacorp" : { }
}

// game indexの確認
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

ビンゴ!!。リストアでデータを復活させる場合は、indexを削除しないといけないようである。

さて、次はログの学習です。

では、また。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

ElasticSearch 決定版ガイドで学習 その3

ElasticSearch導入のための学習とまとめ。

環境

  • vagrant1.7.2
  • centos6.5

Search with Query DSL

JSON request bodyを使って検索ができる。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}'

// 結果

{"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.30685282,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

More-Complicated Searches

もうちょい複雑な検索をしてみる。filterを利用する。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "filtered" : {
            "filter" : {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            },
            "query" : {
                "match" : {
                    "last_name" : "smith" 
                }
            }
        }
    }
}'

// 結果
{"took":11,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

gtはgreater than。

Full-Text Search & Phrase Search

さらにもうちょい複雑な検索をしてみる。rock climbingが趣味のユーザーを取得する。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    }
}'

// 結果

{"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.23013961,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.23013961,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
}]}}

"rock" と "climbing" の両方を含んでいるデータを取得する場合は、match_phraseで検索する。matchだと"rock" と "climbing"のいづれか一つのフレーズがマッチしただけで結果を取得することになる。

Highlighting Our Searches

ハイライトさせたいときはhighlight parameterを加える。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}'

// 結果

{"took":51,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.23013961,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.23013961,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
,"highlight":{"about":["I love to go rock climbing"]}}]}}

Analytics

集合を操れる。ここは割愛。上記までのやり方が理解できてれば、全然難しくない。
ここより先は、必要な時、もっと理解を深めたいときに読むと良いとのこと。

というわけで導入の決定版ガイドで学習は終了になります。次は既存のmysqlと連携して利用してみようと思います。
また具体的に学習する項目があれば、こんな感じでやっていこうと思います。

では、また。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月6日金曜日

ElasticSearch 決定版ガイドで学習 その2

ElasticSearch導入のための学習とまとめ。

環境

  • vagrant1.6.5
  • centos6.5

Talking to Elasticsearch

Elasticsearchへリクエストを送る場合、以下の構文を使用する


curl -X<VERB> '<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>' -d '<BODY>'

例:クラスターの中のドキュメントの数をカウント

コマンドで叩きます


curl -XGET 'http://192.168.33.19:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 0,
  "_shards" : {
    "total" : 0,
    "successful" : 0,
    "failed" : 0
  }
}

まだ何もやってないので、全部0なのかな。多分。header情報も見たいときはcurlに-iオプションを追加する。


curl -i -XGET 'http://192.168.33.19:9200/'
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 347

{
  "status" : 200,
  "name" : "Hate-Monger",
  "cluster_name" : "elasticsearch-changed",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

ちゃんとheaderが表示できましたね。

Document Oriented

Elasticsearchはドキュメントベースでデータを管理し、jsonを利用している。indexもドキュメント。

Finding Your Feet

チュートリアルをやってElasticsearchを理解しよう。ここでは従業員のディレクトリを作ってチャレンジするよ。要件は以下

  • 複数のタグ、値、数値、テキストを含むデータを利用できる
  • あらゆる従業員の詳細を検索する
  • 30歳以上の従業員を見つけるような、構造化された検索を許可
  • 単純なフルテキスト検索と、より複雑なフレーズ検索を許可
  • 一致するドキュメントのテキストの中から、強調された検索の断片を返す
  • 分析的なダッシュボードを作成できる

Indexing Employee Documents

Elasticsearchにデータを保存することを「indexing」と呼ぶ。
「indexing」の前に保存場所を決める。
Elasticsearchでは、documentはtypeに属する。これらのtypeはindexの中にあるよ。

Relational DB ⇒ Databases ⇒ Tables ⇒ Rows ⇒ Columns
Elasticsearch ⇒ Indices ⇒ Types ⇒ Documents ⇒ Fields

データの登録


curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/1' -d '
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
'

{"_index":"megacorp","_type":"employee","_id":"1","_version":1,"created":true}

/megacorp/employee/1に3つの情報が含まれているのに注意。

megacorp : The index name
employee : The type name
1 :The ID of this particular:employee

うまく登録できたみたいなので、ブラウザから叩く。


// ブラウザで叩く
http://192.168.33.19:9200/megacorp/employee/1

// 結果表示

{"_index":"megacorp","_type":"employee","_id":"1","_version":1,"found":true,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
}

成功です。どんどん登録します。


// 登録

curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/2' -d '
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
'

// 登録

curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/3' -d '
{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
'

// 確認

curl -XGET 'http://192.168.33.19:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

Search Lite

簡単な検索の学習。まずは「単純検索」


// ブラウザ
http://192.168.33.19:9200/megacorp/employee/_search

{"took":22,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"3","_score":1.0,"_source":
{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
}]}}

「条件を付加して検索」


// ブラウザ
http://192.168.33.19:9200/megacorp/employee/_search?q=last_name:Smith

{"took":22,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.30685282,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

長くなるので分割。
次はSearch with Query DSLからです。
どこまできちんとメモするか微妙です。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

ElasticSearch 決定版ガイドで学習 その1

ElasticSearch導入のための学習とまとめ。後でもっと綺麗にまとめます。多分・・・。

環境

  • vagrant1.6.5
  • centos6.5

javaをinstall

Elasticsearchを動かすにはjavaが必要なのでインストール


// 動作に必要なjavaの導入
yum install java-1.7.0-openjdk

Elasticsearch install

rpm版をダウンロードして利用します


// rpm DLしてinstall
sudo rpm -ivh https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.noarch.rpm

### NOT starting on installation, please execute the following statements to configure elasticsearch to start automatically using chkconfig
 sudo /sbin/chkconfig --add elasticsearch
### You can start elasticsearch by executing
 sudo service elasticsearch start

// chkconfigは有効にしないで実行
sudo service elasticsearch start

ブラウザを開いてhttp://192.168.33.19:9200/にアクセス。(192.168.33.19はvagrantで適当に指定)


{
  "status" : 200,
  "name" : "Brigade",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

きちんと動作しています。

さて、まずは基本からきっちり学んでいきましょう。急がばまわれはいつの時代、どこの世界も共通項。

まずは公式サイトのdefinitive guideに目を通します。せっかくなので日本語に翻訳した超短縮要訳も載せておきます。

決定版ガイド超短縮要訳

who should read this book

Elasticsearchは素晴らしい技術だよ。規約に沿っている限りは、楽々スケールできる。
製品版の前に安定したクラスターの作り方を理解しなさい。
メルトダウンを避けるためにもガイドは読もうな。

Why We Wrote This Book

Elasticsearchは説明が必要だ。このガイドは初心者に理解できるように書いたよ。
既存のリファレンスドキュメントは機能の使い方を説明している。このガイドでは、なぜ、そしていつ、Elasticsearchの様々な機能を使うべきかを説明しよう。

Elasticsearch version

1.4.0について説明する。でも、すぐ進化するから気をつけてね。

How to Read This Book

複雑なプロセスもきちんと理解しよう。
Life Inside a Cluster, Distributed Document Store, Distributed Search Execution, and Inside a Shardを読むと理解が深くなるよ。だから、ちゃんと読んどきー。
最初は順番に読んでいきなさい。Proximity Matching and Partial Matchingは必要に応じて読みなさい。

Navigating This Book

7つのパートがある

「you know, for search」…から「Inside a Shard」は基本。いいからやれ。

「Structured search…」から「Controlling Relevance」は文字の有意(確率的に偶然とは考えにくく、意味があると考えられる)性や部分マッチ。

「Getting Started with Languages」から「Typoes and Mispelings」は語幹処理、類語、あいまい検索。

online resources, conventions used in this book,using code examples, acknowledgments

不要

you know, for search

Luceneは素晴らしい検索エンジンだが複雑だ。Elasticsearchはもっと素晴らしい検索エンジンなうえに簡単だ。

Installing Elasticsearch

marvel入れるとブラウザで見れて便利だよ。無料じゃないので注意。

Installing Elasticsearch

cluster.nameはデフォルトでなく、適当な名称に変更しなさい。同じネットワーク内で動かすなら一意な名前にしないと駄目だよーん。
cluster.nameはconfigディレクトリのelasticsearch.ymlを変更して再起動すれば変更できます。


// conf
cd /etc/elasticsearch

ls -l
-rw-r--r-- 1 root root 13476 Dec 16 14:12 elasticsearch.yml
-rw-r--r-- 1 root root  1512 Dec 16 14:12 logging.yml

vi elasticsearch.yml


################################### Cluster ###################################

# Cluster name identifies your cluster for auto-discovery. If you're running
# multiple clusters on the same network, make sure you're using unique names.
#
cluster.name: elasticsearch-changed

再起動して、ブラウザを開いてhttp://192.168.33.19:9200/に再びアクセス。


// 再起動
sudo service elasticsearch restart

{
  "status" : 200,
  "name" : "Hate-Monger",
  "cluster_name" : "elasticsearch-changed",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

cluster_nameが変更されているのが確認できました。

シャットダウンは、Ctrl-Cか、shutdown APIを呼びだしなさい


curl -XPOST 'http://192.168.33.19:9200/_shutdown'

コマンド叩くとelasticsearchが止まります。

長くなるので続きます。
次はTalking to Elasticsearchからです。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月2日月曜日

組織の作りかた - how to make an organization -

さて、ソフトウェアの新規プロジェクトを始めるときに必要になるのが、組織の設計です。
小さいプロジェクトだと優秀なエンジニアが2-3人いればどうにかなってしまうけど、それなりの規模と継続性が求められる案件をコアメンバー中心で回すとブラックボックスシステムになってしまいます。

優秀なエンジニアが複数人いれば幸運なほうで、一人しかいなかったりした場合その人が辞めたりしたら・・・なことになってしまうので、開発環境を整える前に組織を整えていくのはすごく大切です。

でも、大抵のプロジェクトはあらかじめ神(上の人達)に決められたメンバーでなんとかやりくりするしかないわけで、だからプロジェクトってすぐ炎上する。 最近は色々と便利なツールやサービスも提供されています。でも、必ずしも最新技術のベストプラクティスに合わせられるメンバーがそろっているわけでもない。むしろそんな組織やチームは稀。 ひどい場合は、「excelもよくわかりませーん」なんてメンバーもいたりする。

組織をどうマネジメントするかってすごく大事なんだけど、やっぱりエンジニアは技術に解決策を求めちゃう傾向がある。もちろん僕自身もその傾向が強いです。

さて、前置きが長くなりました。

要は僕が何が言いたいかというと、今後はエンジニアが、組織やチームをスケールする技術を身につけるべきだってこと。

というのも、最近は色々と素敵な技術が編み出されているけど、それを使える(使っている)のは一部のエンジニアだけ。
だからこそ、プロジェクトを組んだメンバーのITスキルや知識を見極めて、プロジェクトに応じた適切なツールを導入していくのは、エンジニアが行うのが適切なんじゃないかな。

もちろん腕の良いプロマネがいれば、そういったことを一任してしまうのが一番なんだけど、そういう人ってほんとレアな人材。 出現率は、はぐれメタルと変わらない。いや、むしろもっと低い。

なので、プロジェクトを上手く回すには、力のあるエンジニアが各メンバーの力や適性を把握して、ツールややり方をコントロールしていくのが一番。 優秀なエンジニアってなんだかんだで、マネジメントスキルやマネタイズだったりも最終的に一番できるようになります。最初は「向いてない」とか言って、すごい嫌がるけど。

なので、エンジニアは是非是非、チームの力量に応じた組織の作り方の技術を身につけていきましょう。 結局は、それが自分も一番楽になれますから。

以下、参考になるサイトです。

以上です。久しぶりの技術以外の書き起こしでしたー。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月1日日曜日

swift Alamofireを使う 詳細編

今回はAlamofireを使ってAPIからデータを取得するコードを詳細に実装していきます。
Alamofireの導入方法はここに記載済みです。

環境

  • Xcode Version 6.1 (6A1052d)

AlamofireでAPIデータ取得

以下は公式サイトの例を元に作成したコード


        Alamofire.request(.GET, "http://test/api/v1/tests", parameters: ["offset": 0, "limit": 1, "test_id": 1])
            .responseJSON { (request, response, JSON, error) in
                if (response?.statusCode == 200) {
                    println("success")
                    println(JSON)
                } else {
                    // error
                    println(error)
                }
        }

上記の処理に例外処理を追加したのが以下の処理になります


    /**
    APIXXXXに接続する.
    
    */
    func connect() {
        
        Alamofire.request(.GET, "http://test/api/v1/tests", parameters: ["offset": 0, "limit": 1, "test_id": 1])
            .responseJSON { (request, response, data, error) in

                if (response?.statusCode == 200) {
                    println("success")
                    let json = SwiftyJSON.JSON(data!)
                    println(json)
                    return;
                }

                self.showAlertView(response)

        }

    }

    /**
    AlertViewを表示.
    
    :response: HTTPレスポンス.
    
    */
    func showAlertView(response :NSHTTPURLResponse?) {
        
        // 定数
        var const = Const()
        // API共通処理
        var apiCommon = APICommon()
        var alert = UIAlertView()
        
        // Optional型の変数が値をもっていた場合(responseが返ってきた場合)の処理
        if (response != nil) {
            println("is response")
            alert.title = apiCommon.getAlertTitle(response!.statusCode)
            alert.message = apiCommon.getAlertMessage(response!.statusCode)
        // Optional型の変数が値をもっていない場合(responseが返ってこない場合)の処理
        } else {
            println("no response")
            alert.title = apiCommon.getAlertTitle(0)
            alert.message = apiCommon.getAlertMessage(0)
        }
        
        alert.addButtonWithTitle("OK")
        alert.show()
    }


変更後のコードの説明

Alamofireの結果のresponseはoptional value宣言で実装されています。そのため、
!を付けた場合は変数の中身がnilだと実行時にエラーになり、?を付けた場合は変数の中身がnilだとエラーにはなりません

responseの中身がnilの場合というのはサーバーが落ちている場合です。
上記の例では、nil(サーバーが落ちている)の場合は、UIAlertViewでサーバーが利用できない旨の表示をする実装をしています。

nil以外(レスポンスはあるが200以外のステータスコードが返ってくる)の場合は、共通クラスでステータスコードに応じたタイトルとメッセージを取得してUIAlertView画面を表示しています。

swiftで実装する場合、optional valueかどうかを意識することがかなり重要になります。というのは、!を付けた場合は変数の中身がnilだと実行時にエラーになります。つまり、実際にアプリを動かしてからエラーが発生します。
プログラミングは習うより慣れろなので、swiftを実装する際は、いつも通りのコーディングパターンに落としこむのでなく、色々なパターンを試してみると良いでしょう。

以上

追伸 : swiftのプログラムコメントはここを参考にしています。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...